home *** CD-ROM | disk | FTP | other *** search
- NAME msyibm
- ; File MSYIBM.ASM
- include mssdef.h
- ; Copyright (C) 1982,1993, Trustees of Columbia University in the
- ; City of New York. Permission is granted to any individual or
- ; institution to use, copy, or redistribute this software as long as
- ; it is not sold for profit and this copyright notice is retained.
- ; edit history:
- ; 6 Sept 1991 version 3.11
- ; Last edit 9 June 1993
- ; 9 May 1993 Add test for Japanese DOS and if present avoid Int 15h. Presence
- ; is held in tv_mode bit 20h.
- ; 12 April 1993 apply 5 dot compressed font (compressed text) to VT emulators
- ; via option SET TERM COMPRESS GRAPHICS
- ; 14 Jan 1993 Add expanded memory usage for screen rollback buffer
- ; 25 June 1992 Multiple TCP/IP session support, revise segmenting, virtual
- ; screens, horizontal scrolling, Connect mode macro at entry, DG support.
- ; 23 Dec 1990 Add Bert Tyler's (NIH) IBM XGA 132 column code.
- ; 9 May 1989 Add Bert Tyler's (NIH) new screen rollback routines.
- ; 21 Jan 1989 be more tolerate of propriatary video modes above 18 when
- ; determining screen segment, Tnx to Terry Kennedy. Add check for IBM
- ; 85xx monitors on Video 7 boards, no 132 columns if it is the monitor.
- ; Retain 43 rows on Video 7 boards.
- ; 30 Nov 1988 Add SET TERM CLEAR screen clearing support.
- ; 28 Nov 1988 Accomodate Tseng Labs UltraPAK mono/Herc board w/132 cols.
- ; 132 column mode is 18h. Requires Tseng's BIGSCR.COM (use BIGSCR /R:25
- ; to enable 132x25 feature). Thanks to Tseng Labs for technical support.
- ; 21 Nov 1988 Version 2.32
- ; 14 Nov 1988 Write a space during lclini to obtain default screen colors.
- ; 12 Nov 1988 Add procs vtrmac and vtsmac to allow exit from Connect mode and
- ; invokation of macros TERMINALR and TERMINALS by reception of escape seqs
- ; in file mszibm.asm or by keyboard verbs.
- ; 7 Oct 1988 Reverse left/right arrow key codes when writing right to left.
- ; 24 Sept 1988 Make output to printer be buffered and flow controlled.
- ; 1 July 1988 Version 2.31
- ; 19 June 1988 Add Everex EVGA support, from Terry Kennedy.
- ; 10 June 1988 Add oldsp and procedure endcon to exit Connect mode if output
- ; fails, mostly for networking (but we don't know that here).
- ; 23 May 1988 Add Everex EV-659 ega board test from Alex Zliu. Fixed incorrect
- ; screen width assumption at startup.
- ; 29 March 1988 Include flag ttyact to group string bytes into one net packet,
- ; thanks to Paul Fox of AT&T.
- ; 23 March 1988 Add "fairness" word to let serial port deliver max chars
- ; between kbd reads, for connect mode only. [jrd]
- ; 10 Feb 1988 Revise getcirc and vtscrX routines to do proper scrolling with
- ; MS Window 1.0x/2.0x [jrd].
- ; 9 Feb 1988 Mode line again. Make flags.modflg 0 for off, 1 for on and owned
- ; by Kermit, and 2 for on and owned by remote host (toggling suppressed).
- ; 25 Jan 1988 Add global byte SCROLL, set in msz, to control emulator screen
- ; scrolling for higher speeds. [jrd]
- ; 5 Jan 1988 Restore cursor codes broken by Tek code additions. [jrd]
- ; 1 Jan 1988 version 2.30
-
- public term, lclyini, termswapout, termswapin, termswapdel
- public prtbout, prtnout, csrtype, fcsrtype, scrseg
- public atsclr, vtscru, vtscrd, trnmod, vclick, vtbell
- public chgdsp, vtroll, crt_lins, crt_cols, tv_mode, vtclear
- ; action verb procedures for keyboard translator
- public uparrw, dnarrw, rtarr, lfarr, pf1, pf2, pf3, pf4
- public kp0, kp1, kp2, kp3, kp4, kp5, kp6, kp7, kp8, kp9
- public kpminus, kpcoma, kpenter, kpdot, chrout, cstatus, cquit
- public cquery, dmpscn, vtans52, vtinit, dnwpg, upwpg, endwnd, homwnd
- public upone, dnone, trnprs, dumpscr, modlin, snull, ignore_key
- public klogon, klogof, cdos, chang, khold, product
- public vtksmac, vtkrmac, apcmacro, apcenable, vtenqenable
- public decf6,decf7,decf8,decf9,decf10,decf11,decf12,decf13,decf14
- public dechelp,decdo,decf17,decf18,decf19,decf20, udkclear
- public decfind, decinsert, decremove, decselect, decprev
- public decnext, setudk, extmacro, vtmacname, vtmaclen
- public rtone, lfone, rtpage, lfpage, kbdcompose
- public dgkc1,dgkc2,dgkc3,dgkc4,dgkf1,dgkf2,dgkf3,dgkf4,dgkf5
- public dgkf6,dgkf7,dgkf8,dgkf9,dgkf10,dgkf11,dgkf12,dgkf13
- public dgkf14,dgkf15, dgpoint, dgnckey
-
- public vtemu, crt_mode, scbattr, refresh, low_rgt ; data
- public setchtab, ftogmod, extattr, vtcpage
- public setpos, getatch, setatch, yflags
- public getbold, setbold, clrbold, getblink, setblink, clrblink
- public getunder, setunder, clrunder, revideo, revscn, setcolor
- public setrev, clrrev, frepaint, touchup
- public vts, vtstat, termtb, modbuf ; terminal emulation
- public nextses, vtinited, setprot, clrprot, qsetatch
- public dgsettek
-
- ; some definitions
- SIchar equ 0fh
- SOchar equ 0eh
- DGescape equ 1eh
-
- ; hardware
- crt_status equ 3dah ; CGA crt status port
- disp_enb equ 8 ; CGA display enable bit
- crtmset equ 3D8H ; CGA CRT mode set port
- screen equ 10h ; Bios screen interrupt
-
- emsint equ 67h ; EMS interrupt
- xmspresent equ 4300h ; EMS presence check for XMS mgr
- emsmgrstat equ 40h ; EMS get manager status
- emsgetseg equ 41h ; EMS get segment of page frame
- emsgetnpgs equ 42h ; EMS get number free pages
- emsalloc equ 43h ; EMS get handle and allocate memory
- emsmapmem equ 44h ; EMS map memory
- emsrelease equ 45h ; EMS release mapped memory
- emsgetver equ 46h ; EMS get version number
- emssetname equ 5301h ; EMS LIM 4, set name
-
- att_bold equ 08h ; bold in main video word
- att_blink equ 80h ; blinking in main video word
- att_intensity equ 08H
- att_protect equ 01h ; protected in vsatt
- att_uline equ 02h ; underscored in vsatt
- att_rev equ 04h ; reversed video in vsatt
-
- att_low_mask equ 06H ; Various attribute-related equates
- att_normal equ 07h
- att_underline equ 01H ; for mono monitors, in video word
-
- modfrm struc ; format of mode (status) line
- db 'Esc-chr: ' ; do not write in last column
- m_echr db 2 dup (' ')
- db ' help: '
- m_hlp db 2 dup (' ')
- db '? port:'
- m_prt db 1 dup (' ')
- db ' speed:'
- m_baud db 6 dup (' ')
- db 'parity:'
- m_par db 4 dup (' ')
- db ' echo:'
- m_echo db 3 dup (' ')
- m_term db 13 dup (' ') ; 13 bytes for term type
- m_prn db 3 dup (' ') ; show PRN when printer is on
- m_comp db ' ' ; Compose indicator
- db '$' ; terminator
- modfrm ends
-
- ; structure for status information table sttab.
- stent struc
- sttyp dw ? ; type (actually routine to call)
- msg dw ? ; message to print
- val2 dw ? ; needed value: another message, or tbl addr
- tstcel dw ? ; address of cell to test, in data segment
- basval dw 0 ; base value, if non-zero
- stent ends
-
-
- data segment
- extrn flags:byte, mar_top:byte, mar_bot:byte, portval:word
- extrn filtst:byte, dmpname:byte, kbdflg:byte, rxtable:byte
- extrn anspflg:byte, tekflg:byte, scroll:byte, ttyact:byte
- extrn holdscr:byte, taklev:byte, takadr:word, mcctab:byte
- extrn trans:byte, npages:word, comand:byte, apctrap:byte
- extrn denyflg:word, tekgraf:byte, rdbuf:byte, dupflg:byte
- extrn chcontrol:byte, kbcodes:byte, repflg:byte, tekcursor:byte
- extrn decbuf:byte, param:word, nparam:word, prnhand:word
- extrn upss:byte, comptab:byte, GRptr:word, G1set:byte, G2set:byte
- extrn G3set:byte, kstatus:word, cursor:word, linescroll:byte
- extrn sescur:word, tcphost:byte, savezlen:word, savezoff:word
- extrn seslist:byte, savexoff:word, savexlen:word, savepoff:word
- extrn saveplen:word, rollwidth:word, dgkbl:byte, apcstring:word
- extrn blinkdis:byte, protectena:byte, dghscrdis:byte
- extrn dgwindcomp:byte, cursorst:byte, dgcross:byte
- extrn emsrbhandle:word, curattr:byte, saveuoff:word, saveulen:word
- extrn savegoff:word, saveglen:word, dosnum:word
- extrn parmsk:byte, flowon:byte, flowoff:byte, flowcnt:byte
-
- inited equ 08h ; been here before
- prtscr equ 1 ; print screen pressed
- ; stuff for screen routines
- ;;;;;;;;;;;;;; start session save area
- even
- saveyoff label word
- yflags db 0 ; status flags
- vtemu emulst <> ; emulator flags
- belltype db 0 ; 0 = aural bell, 1 = visual
- scbattr db ? ; screen background attribute
- savattr db ? ; current emulator attributes
- extattr db 0 ; extended scbattr
- crt_mode db 3 ; video mode (typ 3, must be text)
- ; keep crt_cols & crt_lins in order
- crt_cols db 80 ; number of screen columns (typ 80)
- crt_lins db 24 ; number of screen rows - 1 (typ 24)
- low_rgt dw 174fh ; lower right corner of text window
- ; high = row address (typ 23)
- ; low = column address (typ 79)
- handhsc db 0 ; hand horizontal scroll
- dosetcursor dw -1 ; place to set tekcursor, -1 = don't
- vtinited db 0 ; flag for emulator having been inited
- vtclear db 0 ; nonzero to redo emulator screen
- writemode db 0 ; screen writing mode
- vtcpage dw 437 ; terminal code page
- apcenable db 1 ; enable APC macro (default is on)
- vtenqenable db 0 ; enable Answerback
- saveflag flginfo <> ; copy of flags array
- ytermtype dw 0
- ymodetype db 0
- saveylen dw ($ - saveyoff)
- ;;;;;;;;;;;;;;;;; end of session save area
-
-
- modbuf modfrm <> ; mode line buffer
- argadr dw 0 ; address of arg blk
- skip dw 0
- inemulator db 0 ; non-zero if term emlator active
-
- vid7id db 'VEGA BIOS Code, ' ; Video 7 Vega version string subset
- vid7len equ $-vid7id ; length of string
- vid7id2 db 'Video Seven BIOS Code, ' ; Video 7 VGA board
- vid7len2 equ $-vid7id2
- atiwid db 'ATI EGA Wonder Bios,' ; ATI EGA wonder version string subset
- atilen equ $-atiwid ; length of string, inc terminator
- atiwid2 db '761295520' ; ATI signature #2
- atilen2 equ $-atiwid2
- tsngid db 'Tseng' ; Tseng Labs EVA (& Orchid Designer)
- tsnglen equ $-tsngid
- stbvid db 'TVGA' ; STB VGA/EM (also Tseng TVGA)
- stbvlen equ $-stbvid
- stavid db '4000' ; STB VGA/EM Plus (Tesng 4000)
- stavlen equ $-stavid
- evrxid db 'Everex' ; Everex Micro Enhancer Deluxe EGA
- evrxlen equ $-evrxid
- evgid db 'VGA EV673' ; Everex EVGA EV-673
- evglen equ $-evgid
- evvid db 'EV-678' ; Everex Viewpoint EV-678
- evvlen equ $-evvid
- attvdc6 db '003116' ; AT&T video board, at c000:35h
- attvdlen equ $-attvdc6
- attvdc7 db 'C02000' ; AT&T video board, at e000:10h
- pmega1 db '28190-A1001' ; Paradise AutoSwitch EGA Mono String1
- pmegal1 equ $-pmega1
- p30id db 'VGA' ; VGA Plus, Plus 16, Professional
- p30ln equ $-p30id ; and VGA1024 by Paradise
- emsrollname db 'KERMIT ',0 ; 8 byte EMS region name, + safety
- pageready dw -1 ; ems page currently active
- cols80 db 'COLS80.BAT',0 ; to 80 column mode batch file
- cols132 db 'COLS132.BAT',0 ; to 132 column mode batch file
- xga_reg_base dw -1 ; PS/2 MCA I/O register base
- ega_mode db 0 ; non-zero if IBM EGA is in use
- tvhere equ 0feh ; Topview active query
- tvsynch equ 0ffh ; Topview resynch request
- tv_segs dw 0 ; Topview virtual screen, segment
- tv_sego dw 0 ; and offset
- tv_mode db 0 ; flag, 0 = no Topview or DESQview
- vs_ptr dd 0 ; offset, segment of vscreen (dynamic)
- vsat_ptr dd 0 ; offset, segment of vs's attributes
- ; Note: (vswidth+1)/2 bytes of attributes/line, at two attributes/byte
- vswidth equ 207 ; columns across DG virtual screen
-
- ; The following are used to turn the display back on (after scrolling etc.)
- msets db 2CH,28H,2DH,29H,2AH,2EH,1EH,29H
- dgcurtab db 23,26,24,25 ; ANSI to DG cursor converter
- dgcrostab db 72,80,77,75 ; DG cursor to PC scan for croshair
-
- mtty db ' TTY ' ; no terminal type (mode line)
- fairness dw 0
- fairprn dw 0
- lincur dw ? ; cursor type save area
- dosattr db ? ; screen attributes at init time
- userbold db 0 ; screen bold attribute at start up
- dos_cols db 0 ; screen width (crt_cols) at DOS
- oldsp dw 0 ; offset to longjmp to for i/o failure
- ten db 10 ; byte constant for key defines
- temp dw 0 ; scratch storage
- temp2 dw 0 ; scratch storage
- dmphand dw -1 ; screen dump file handle
- dumpsep db 0ch,cr,lf ; screen image separators
- dmperr db ' Cannot open file to save screen to disk $'
- memerr db cr,lf,'Not enough memory for terminal emulator$'
- crlf db cr,lf,'$'
- pntmsg db 'Printer not ready, printing request skipped$'
- upsshlp db ' User Preferred Supplemental Set:'
- db cr,lf, 'DEC-MCS, Latin-1, Hebrew-7, Hebrew-ISO$'
- apchlp db cr,lf,'ON to allow APC cmd from host to invoke commands'
- db ' (default)'
- db cr,lf,'OFF to prevent all use of APC from the host'
- db cr,lf,'UNCHECKED to allow any command to be executed$'
- enqhlp db cr,lf,'ON to permit Answerback to Control-E Enquire request'
- db ' (def=off)$'
- ; some static data for mode line
- modmaster modfrm <> ; master template
- unkbaud db 'unkwn ' ; must be 6 chars
- baudn db ' 45.5 ',' 50 ',' 75 ',' 110 ','134.5 ',' 150 ',' 300 '
- db ' 600 ',' 1200 ',' 1800 ',' 2000 ',' 2400 ',' 4800 ',' 9600 '
- db '14400 ', '19200 ','28800 ', '38400 ','57.6K ','115 K '
- db '75/12 '
- baudnsiz equ 21 ; # of baud rates known (tbl size / 6)
- repmsg db 'REPLAY' ; REPLAY message for speed field
- repmsgl equ $-repmsg
- parnams db 'even','mark','none','odd ','spc '
- lclmsg db 'loc'
- remmsg db 'rem'
- portno db 0
-
- ; storage for multi-window stuff
- slen equ 24 ; and length of text
- crt_norm db 3 ; video mode for normal screen
-
- inipara dw 0 ; initial paragraphs of scroll memory
- ; also is number ems pages for same
- refresh db 0 ; screen refresh (0=wait for retrace)
- vtroll db 0 ; auto roll back allowed (0 = no)
- useexp db 0 ; non-zero to use exp mem for rollback
- vsbuff_inited db 0 ; non-zero if inited screen buffers
- setnoshow db 0 ; quiet setatch flag
-
- vtkrname db 'KEYBOARDR' ; a macro name, must be Upper Case
- vtkrlen equ $-vtkrname
- vtksname db 'KEYBOARDS' ; a macro name, must be Upper Case
- vtkslen equ $-vtksname
- prodname db 'PRODUCT'
- vtplen equ $-prodname
- vtsesname db 'SESSION'
- vtsesnum db '1'
- vtseslen equ $-vtsesname
-
- vtmacname dw vtkrname ; pointer to selected macro name
- vtmaclen dw vtkrlen
- udkseg dw 18 dup (0) ; segment of user definable key defs
- even ; screen rollback material
- iniseg dw ? ; (BDT) initial seg of scroll memory
- ppl dw 0 ; (BDT) paragraphs per line
- lcnt dw 0 ; (BDT) number of "filled" buffer lines
- linef dw 0 ; (BDT) "first" filled line is here
- linec dw 0 ; (BDT) "current" screen line number
- linee dw 0 ; (BDT) total # of lines in the buffer
- lmax dw 0 ; (BDT) max lines in buff (less 1 scrn)
- lineems dw 0 ; lines per EMS 16KB page frame
-
- tsave dw 6 dup (0) ; list of term swap paragraphs
-
- ; DG SPCL three stroke Compose key
- grab dw 0 ; zero if not grabbing output
- grabbox db 0,0 ; store incoming pair of bytes
-
- setchtab db 10 ; Set File Character-Set table
- mkeyw 'CP437',437 ; hardware default Code Page
- mkeyw 'CP850',850 ; Multilingual CP
- mkeyw 'CP852',852 ; Latin2 CP
- mkeyw 'CP860',860 ; Portuguese CP
- mkeyw 'CP861',861 ; Icelandic CP
- mkeyw 'CP862',862 ; Hebrew CP
- mkeyw 'CP863',863 ; French Canadian CP
- mkeyw 'CP865',865 ; Norwegian CP
- mkeyw 'CP866',866 ; Latin5/Cryillic CP
- mkeyw 'Shift-JIS',932 ; Japanese Shift-JIS
- ;; mkeyw 'User-defined',1 ; User loadable table
-
- ; begin Terminal emulator data set
- termtb db tttypes ; entries for Status, not Set
- mkeyw 'VT320',ttvt320
- mkeyw 'VT220',ttvt220
- mkeyw 'VT102',ttvt102
- mkeyw 'VT100',ttvt100
- mkeyw 'VT52',ttvt52
- mkeyw 'Honeywell VIP7809',tthoney
- mkeyw 'Heath-19',ttheath
- mkeyw 'Tek4010',tttek
- mkeyw 'PT200',ttpt200
- mkeyw 'D463',ttd463
- mkeyw 'D470',ttd470
- mkeyw 'none',ttgenrc
-
-
- vttbl db 43 ; number of entries
- mkeyw 'Answerback',vtenqctl
- mkeyw 'APC-macro',apcctl
- mkeyw 'Arrow-keys',flg11
- mkeyw 'Character-set',vtchar
- mkeyw 'Code-Page',vtcodepage
- mkeyw 'Compressed-text',flg14
- mkeyw 'Controls',flg9
- mkeyw 'Cursor-style',flg7
- mkeyw 'Direction',flg4
- mkeyw 'Expanded-memory',expmemory
- mkeyw 'Horizontal-scroll',flg13
- mkeyw 'Keyclick',flg5
- mkeyw 'Keypad',flg10
- mkeyw 'Margin-bell',flg6
- mkeyw 'Newline',flg1
- mkeyw 'Screen-background',flg8
- mkeyw 'Video-writing',scrwrite
- mkeyw 'Tabstops',tabmod
- mkeyw 'Width',flg12
- mkeyw 'Wrap-lines',flg2
-
- mkeyw 'Bell',vtbeep
- mkeyw 'Bytesize',vtbyte
- mkeyw 'Clear-screen',vtcls
- mkeyw 'Color',vtcolor
- mkeyw 'Display',vtbyte ; syn for set display 7/8
- mkeyw 'Graphics',vtgraph
- mkeyw 'Replay',replay
- mkeyw 'Rollback',vtrollbk
- mkeyw 'output-shift',vtshift
- mkeyw 'UPSS',vtupss
- mkeyw 'Type',vttype ; SET TERM TYPE
- mkeyw 'None',vttyp0
- mkeyw 'Heath-19',vttyp1
- mkeyw 'VT52',vttyp2
- mkeyw 'VT100',vttyp4
- mkeyw 'VT102',vttyp8
- mkeyw 'VT220',vttyp10
- mkeyw 'VT320',vttyp20
- mkeyw 'Tek4010',vttyp40
- mkeyw 'Honeywell',vttyp80
- mkeyw 'PT200',vttyp100
- mkeyw 'D463',vttyp200
- mkeyw 'D470',vttyp400
-
- ontab db 2 ; two entries
- mkeyw 'off',0
- mkeyw 'on',1
-
- beltab db 3 ; bell type
- mkeyw 'audible',0
- mkeyw 'visual',1
- mkeyw 'none',2
-
- distab db 2 ; display
- mkeyw '7-bit',0
- mkeyw '8-bit',d8bit
-
- scrtab db 2 ; screen attributes
- mkeyw 'normal',0
- mkeyw 'reverse',1
-
- dirtab db 2 ; writing direction
- mkeyw 'left-to-right',0
- mkeyw 'right-to-left',1
-
- writetab db 2 ; writing
- mkeyw 'direct',0
- mkeyw 'Bios',1
-
- curtab db 2 ; cursor attributes
- mkeyw 'block',0
- mkeyw 'underline',1
-
- apctab db 3 ; three entries
- mkeyw 'off',0
- mkeyw 'on',1
- mkeyw 'unchecked',2
-
- chatab db 24 ; National Replacement Character sets
- mkeyw 'ASCII',0 ; ASCII is default (0, no NRC)
- mkeyw 'British',1 ; start NRC set (1-12)
- mkeyw 'Dutch',2
- mkeyw 'Finnish',3
- mkeyw 'French',4
- mkeyw 'Fr-Canadian',5
- mkeyw 'German',6
- mkeyw 'Hebrew-7',13
- mkeyw 'Italian',7
- mkeyw 'Norwegian/Danish',8
- mkeyw 'Portuguese',9
- mkeyw 'Spanish',10
- mkeyw 'Swedish',11
- mkeyw 'Swiss',12 ; end of NRC proper
-
- mkeyw 'Alternate-ROM',14 ; Alternate-ROM character set
- mkeyw 'Transparent',15 ; use native display adapter hardware
- mkeyw 'Latin1',16 ; Latin-1 in GR
- mkeyw 'Latin2',23 ; Latin-2 (will presume CP852)
- mkeyw 'Hebrew-ISO',24 ; Hebrew-ISO (presumes CP862)
- mkeyw 'DEC-MCS',17 ; DEC Supplemental Graphics in GR
- mkeyw 'DEC-Technical',18
- mkeyw 'DEC-Special',19
- mkeyw 'DG-International',20
- mkeyw 'DG-Line-Drawing',21
- mkeyw 'DG-Word-Processing',22
-
- upsstab db 4
- mkeyw 'DEC-MCS','5%' ; DEC Supplemental Graphics
- mkeyw 'Latin1','A' ; Latin-1
- mkeyw 'Hebrew-7','4"' ; DEC Hebrew-7
- mkeyw 'Hebrew-ISO','H' ; Hebrew-ISO
-
- sidetab db 4 ; SET TERM CHAR <char set> Gn
- mkeyw 'G0','0'
- mkeyw 'G1','1'
- mkeyw 'G2','2'
- mkeyw 'G3','3'
-
- shifttab db 5 ; SET TERM OUTPUT-SHIFT
- mkeyw 'none',0
- mkeyw 'automatic',8
- mkeyw 'SI/SO',1
- mkeyw 'SS2',2
- mkeyw 'SS3',4
-
- graftab db 12
- mkeyw 'auto-sensing',0 ; autosensing
- mkeyw 'CGA',1
- mkeyw 'EGA',2
- mkeyw 'VGA',3
- mkeyw 'Hercules',4
- mkeyw 'ATT',5
- mkeyw 'WyseA(1280x800)',6 ; Wyse-700 1280 x 800 mode
- mkeyw 'WyseH(1280x780)',7 ; Wyse-700 1280 x 780 mode
- mkeyw 'WyseT(1024x780)',8 ; Wyse-700 1024 x 780 mode
- mkeyw 'character-writing',101h
- mkeyw 'color',103h
- mkeyw 'cursor',102h
-
- gchrtab db 2 ; set term graphics char-writing
- mkeyw 'opaque',1
- mkeyw 'transparent',0
-
- disatab db 2 ; Tek disable/enable table
- mkeyw 'disabled',1
- mkeyw 'enabled',0
-
- tabtab db 2 ; label says it all!
- mkeyw 'at',0FFH ; For setting tab stops
- mkeyw 'Clear',0 ; For clearing tab stops
-
- alltab db 2 ; more tab command decoding
- mkeyw 'all',0
- mkeyw 'at',1
-
- cntltab db 2 ; 8-bit controls
- mkeyw '7-bit',0
- mkeyw '8-bit',1
-
- kpamtab db 2 ; keypad, application
- mkeyw 'numeric',0
- mkeyw 'application',1
-
- arrtab db 2 ; cursor keys, application
- mkeyw 'cursor',0
- mkeyw 'application',1
-
- widtab db 2
- mkeyw '80-columns',0
- mkeyw '132-columns',1
-
- hstab db 2 ; horizontal scrolling
- mkeyw 'auto',0
- mkeyw 'manual',1
-
- cmptab db 2
- mkeyw 'graphics',0
- mkeyw 'text-132',1
-
- colortb db 0,4,2,6,1,5,3,7 ; color reversed-bit setting bytes
- clrset db 0 ; Temp for SET Term Tabstops xxx
-
- erms41 db cr,lf,'?More parameters are needed$'
- vthlp db ' one of the following:',cr,lf
- db ' TYPE of: None, Heath-19, Honeywell VIP7809, VT52,'
- db ' VT100, VT102, VT220,',cr,lf,' VT320 (default), Tek4010,'
- db ' PT200 (Prime), D463 or D470 (Data General)'
- db cr,lf
- db ' Newline-mode Cursor-style Character-set'
- db cr,lf
- db ' Keyclick Margin-bell Screen-background'
- db ' (normal, reverse)',cr,lf
- db ' Tabstops Wrap (long lines) Color (fore & background)'
- db cr,lf,' Answerback response (on or off, default is off)'
- db cr,lf,' APC-macro (APC cmd from host invokes local cmds)'
- db cr,lf,' Arrow-keys cursor (normal) or application mode'
- db cr,lf,' Bell audible or visual or none'
- db cr,lf,' Clear-screen (clears old startup screen)'
- db cr,lf,' Code-Page (overrides default)'
- db cr,lf,' Compressed-text Graphics or Text-132 (for D463/D470)'
- db cr,lf,' Controls 7-bit or 8-bit (permits VT320 to send'
- db ' 8-bit control sequences (C1))'
- db cr,lf,' Direction Left-to-right or Right-to-left'
- db ' (screen writing direction)'
- db cr,lf,' Display or Bytesize 7-bit or 8-bit'
- db cr,lf,' Expanded-memory (for screen rollback), default on'
- db cr,lf,' Graphics (type of display adapter when in Tek4010'
- db ' mode, and char writing)'
- db cr,lf,' Horizontal scrolling, auto (default) or manual'
- db cr,lf,' Keypad numeric (normal) or application mode'
- db cr,lf,' Output-shift (prefix 8-bit data for 7-bit channel)'
- ;;; db cr,lf,' Replay filespec (display a file through the emulator)'
- db cr,lf,' Rollback (undo screen roll back before writing new'
- db ' chars, default=off)'
- db cr,lf,' TEK ENABLE or DISABLE (activation by host command)'
- db cr,lf,' Width 80 or 132 columns, if the adapter can do it'
- db cr,lf,' Video-writing, Direct or via Bios$'
- clrhlp db ' one of the following:'
- db cr,lf,' AT #s (to set tabs at column #s) or'
- db ' AT start-column:spacing'
- db cr,lf,' Clear AT #s (clears individual tabs) or'
- db ' AT start-column:spacing'
- db cr,lf,' Clear ALL (to clear all tabstops)'
- clrhlp2 db cr,lf,' Ex: Set term tab at 10, 20, 34 sets tabs'
- db cr,lf,' Ex: Set term tab at 1:8 sets tabs at 1, 9,'
- db cr,lf,' Ex: Set term tab clear at 9, 17, 65 clears tabs'
- db cr,lf,' Ex: Set term tab clear at 1:8 clears tabs at 1, 9,'
- db ' 17,...$'
- tbserr db cr,lf,'?Column number is not in range 1 to screen width-1$'
- colhlp db cr,lf,' Set Term Color value, value, value, ...'
- db cr,lf,' 0 no-snow mode on an IBM CGA and white on black'
- db cr,lf,' 1 for high intensity foreground'
- db cr,lf,' 10 for fast CGA screen updating (may cause snow)'
- db cr,lf,' Foreground color (30-37) = 30 + sum of colors'
- db cr,lf,' Background color (40-47) = 40 + sum of colors'
- db cr,lf,' where colors are 1 = red, 2 = green, 4 = blue'
- db cr,lf,' Ex: 0, 1, 37, 44 IBM CGA(0), bright(1) white(37)'
- db ' chars on a blue(44) field'
- db cr,lf,' Attributes are applied in order of appearance.$'
- colerr db cr,lf,'?Value not in range of 0, 1, 10, 30-37, or 40-47$'
- expmhlp db cr,lf,' Use expanded memory for screen rollback buffer,'
- db ' on or off$'
- vtwrap db 'Term wrap-lines: $'
- vtbellm db 'Term margin-bell: $'
- vtnewln db 'Term newline: $'
- vtcur db 'Term cursor-style: $'
- vtcset db 'Term character-set: $'
- vtclik db 'Term key-click: $'
- vtscrn db 'Term screen-background: $'
- colst1 db 'Term color foregnd:3$'
- colst2 db ' backgnd:4$'
- vtgraf db 'Term graphics: $'
- vtrolst db 'Term rollback: $'
- vtdir db 'Term direction: $'
- vtcntst db 'Term controls: $'
- vtkpst db 'Term keypad: $'
- vtarst db 'Term arrow-keys: $'
- vtbset db 'Term bell: $'
- vtgchst db 'Term graph char: $'
- vtwdst db 'Term width: $'
- vtupsst db 'Term UPSS: $'
- vtshftst db 'Term output-shift: $'
- vthscst db 'Term horizontal-scroll: $'
- vtapcst db 'Term APC-macro: $'
- vtenqst db 'Term Answerback: $'
- vtwrtst db 'Term video-writing: $'
- vtexpmst db 'Term expanded-memory: $'
- vtcpagest db 'Term Code-Page: $'
- vtcmptst db 'Term compressed-text: $'
- ; terminal emulator
- vtstbl stent <srchkw,vtenqst,ontab,vtenqenable> ; Answerback
- stent <srchkw,vtapcst,apctab,apcenable> ; APC-macro
- stent <srchkw,vtcset,chatab,vtemu.vtchset> ; char set
- stent <srchkb,vtclik,ontab,vskeyclick,vtemu.vtflgop> ; keyclick
- stent <colstat> ; colors
- stent <srchkb,vtwrap,ontab,vswrap,vtemu.vtflgop> ; line wrap
- stent <srchkb,vtcntst,cntltab,vscntl,vtemu.vtflgop> ; controls
- stent <srchkb,vtbellm,ontab,vsmarginbell,vtemu.vtflgop>;margin bell
- stent <srchkb,vtcur,curtab,vscursor,vtemu.vtflgop> ; cursor type
- stent <srchkw,vtbset,beltab,belltype> ; bell
- stent <srchkb,vtdir,dirtab,vswdir,vtemu.vtflgop> ; write direct
- stent <srchkb,vtnewln,ontab,vsnewline,vtemu.vtflgop> ; newline
- stent <srchkw,vtgraf,graftab,tekgraf> ; graphics
- stent <srchkw,vtrolst,ontab,vtroll> ; rollback
- stent <srchkw,vtgchst,gchrtab,chcontrol> ; chr cntrl
- stent <srchkb,vtarst,arrtab,decckm,vtemu.vtflgop> ; arrow-keys
- stent <srchkb,vtscrn,scrtab,vsscreen,vtemu.vtflgop> ; screen
- stent <srchkb,vtkpst,kpamtab,deckpam,vtemu.vtflgop> ; keypad
- stent <srchkb,vtwdst,widtab,deccol,vtemu.vtflgop> ; width
- stent <srchkww,vtupsst,upsstab,upss+1> ; UPSS
- stent <srchkw,vtshftst,shifttab,flags.oshift> ; output-shift
- stent <srchkb,vthscst,hstab,vshscroll,vtemu.vtflgop> ; Horz scroll
- stent <srchkw,vtwrtst,writetab,writemode> ; Writing
- stent <srchkw,vtexpmst,ontab,useexp> ; exp mem
- stent <srchkww,vtcpagest,setchtab,vtcpage> ; Code-Page
- stent <srchkb,vtcmptst,cmptab,vscompress,vtemu.vtflgop> ; compress
-
- stent <tabstat> ; VT320 tab status - needs one whole line
- dw 0 ; end of table
-
- vtmacroptr dd vtmacro ; FAR pointer
- ftogmod dd togmod ; FAR pointer
- termlatch db 0 ; reentry block for session macros
- data ends
-
- data1 segment
- ; structures below: byte cnt of combos, dw input combo list, db output list
- ; using DG International or Latin1 codes for output.
- grl1dgi db 48 ; case and order insensitive
- dw '++','AA','((','//','/<','^ ','(-','/^',')-','<<'
- dw '0^','* ','+-','>>','SS','/U','2^','3^','C/','C|'
- dw 'L-','L=','Y-','Y=','SO','S!','S0','XO','X0','A-'
- dw 'CO','C0','PP','P!','.^','O-','12','!!','??','T-'
- dw 'TM','FF','<=','>=',',-','""',2727h,'RO'
- grc1dgi db '#', '@', '[', '\', '\', '^', '{', '|', '}', 0b1h
- db 0bch,0bch,0b6h,0b0h,0fch,0a3h,0a4h,0a5h,0a7h,0a7h
- db 0a8h,0a8h,0b5h,0b5h,0bbh,0bbh,0bbh,0a6h,0a6h,0a9h
- db 0adh,0adh,0b2h,0b2h,0b9h,0aah,0a2h,0abh,0ach,0afh
- db 0b3h,0b4h,0b7h,0b8h,0a1h,0bdh,0beh, 0aeh
-
- grl1lat db 44 ; case and order insensitive
- dw '<<','0^','* ','+-','>>','SS','/U','2^','3^','C/'
- dw 'C|','L-','L=','Y-','Y=','SO','S!','S0','XO','X0'
- dw 'A-','CO','C0','PP','P!','.^','O-','12','!!','??'
- dw 'TM',',-','""',2727h,'RO','||','--','-^',',,','34'
- dw 'XX','-:','1^','14'
- grc1lat db 0abh,0b0h,0b0h,0b1h,0bbh,0dfh,0b5h,0b2h,0b3h,0a2h
- db 0a2h,0a3h,0a3h,0a5h,0a5h,0a7h,0a7h,0a7h,0a4h,0a4h
- db 0aah,0a9h,0a9h,0b6h,0b6h,0b7h,0bah,0bdh,0a1h,0bfh
- db 0aeh,0ach,0a8h,0b4h, 0aeh,0a6h,0adh,0afh,0b8h,0beh
- db 0d7h,0f7h,0b9h,0bch
-
- grl2dgi db 25 ; case sensitive, order insensitive
- dw '''A','`A','^A','"A','~A','*A','''E','`E','^E','"E'
- dw '''I','`I','^I','"I','~N','''O','`O','^O','"O','~O'
- dw '''U','`U','^U','"U','"Y'
- grc2dgi db 0c0h, 0c1h,0c2h,0c3h,0c4h,0c5h,0c8h, 0c9h,0cah,0cbh
- db 0cch, 0cdh,0ceh,0cfh,0d0h, 0d1h,0d2h,0d3h,0d4h,0d5h
- db 0d8h, 0d9h,0dah,0dbh,0ddh
-
- grl2lat db 25 ; case sensitive, order insensitive
- dw '''A','`A','^A','"A','~A','*A','''E','`E','^E','"E'
- dw '''I','`I','^I','"I','~N','''O','`O','^O','"O','~O'
- dw '''U','`U','^U','"U','''Y'
- grc2lat db 0c1h, 0c0h,0c2h,0c4h,0c3h,0c5h,0c9h, 0c8h,0cah,0cbh
- db 0cdh, 0cch,0ceh,0cfh,0d1h, 0d3h,0d2h,0d4h,0d6h,0d5h
- db 0dah, 0d9h,0d8h,0dch,0ddh
-
- grl3dgi db 7 ; case and order sensitive
- dw 'EO','AE',',C','/O','ae',',c','/o'
- grc3dgi db 0d7h,0c6h,0c7h,0d6h,0e6h,0e7h,0f6h
-
- grl3lat db 10 ; case and order sensitive
- dw 'AE',',C','/O','HT','-D','ae',',c','/o','ht','-d'
- grc3lat db 0c6h,0c7h,0d8h,0deh,0d0h,0e6h,0e7h,0f8h,0feh,0f0h
- data1 ends
- ; end of Terminal data set
- code1 segment
- extrn ans52t:far, vsinit:near ; in mszibm
- extrn anstty:near, ansini:near, ansrei:near ; in mszibm
- extrn anskbi:near, ansdsl:near ; in mszibm
- extrn tabset:near, tabclr:near, dgnctoggle:far
-
- fanskbi proc far
- call anskbi ; in mszibm
- ret
- fanskbi endp
- ftabset proc far
- call tabset ; in mszibm
- ret
- ftabset endp
- ftabclr proc far
- call tabclr ; in mszibm
- ret
- ftabclr endp
- code1 ends
-
- code2 segment
- extrn tekini:far, tekemu:far, tekend:far, tekrint:far ;in msgibm
- extrn ttxtchr:far, ttxtline:far,teksetcursor:far,tekremcursor:far
- extrn croshair:far, dgcrossrpt:far
- code2 ends
-
- code segment
- extrn prtchr:near, outchr:near, sbrk:near, pcwait:near
- extrn isfile:near
- extrn msuinit:near, keybd:near, kbhold:near ; in msuibm
- extrn clrmod:near, putmod:near, cmblnk:near, cptchr:near
- extrn telnet:near, srchkww:near
- extrn atoi:near, strlen:near, srchkb:near, srchkw:near, pasz:near
- extrn prompt:near, comnd:near, statc:near, replay:near
- extrn crun:near, serini:near, spath:near, strcpy:near, tekdmp:near
- extrn prttab:near, dec2di:near, tekgcptr:near
- extrn pntchr:near, pntflsh:near, tcpstart:near, serrst:near
- assume cs:code, ds:data, es:nothing
-
- ; do initialization local to this module
- ; Dynamically allocates 4000 bytes for screen save/restore buffer plus
- ; 320 to 38400 bytes for screen scroll back buffers. Tries to leave space
- ; for Command.com before enlarging buffers.
- lclyini proc near
- call msuinit ; initialize keyboard module msuxxx
- call far ptr flclyini ; far call specifics
- ret
- lclyini endp
-
- ; begin Terminal set & status code
- ; SET Term parameters, especially for use with VT100 emulator.
- ; VTS is called only by mssset to set terminal type and characteristics.
- ; Exit carry set for failure.
- VTS proc near ; SET TERM whatever
- mov kstatus,kssuc ; success
- mov ah,cmkey ; Parse another keyword
- mov bx,offset vthlp ; Use this help
- mov dx,offset vttbl ; Use this table
- call comnd
- jnc vset1 ; nc = success
- ret ; failure
- vset1: call bx ; dispatch to processing routine
- ret
-
- vtcls: mov ah,cmeol ; Clear-screen
- call comnd
- jc vtclsx ; c = failure
- mov vtclear,2 ; set trigger for emulator clear scn
- clc ; success
- vtclsx: ret
-
- ; SET TERM kind
- vttyp0: mov bx,ttgenrc ; NONE
- jmp short vsett1
- vttyp1: mov bx,ttheath ; Heath-19
- jmp short vsett1
- vttyp2: mov bx,ttvt52 ; VT52
- jmp short vsett1
- vttyp4: mov bx,ttvt100 ; VT100
- jmp short vsett1
- vttyp8: mov bx,ttvt102 ; VT102
- jmp short vsett1
- vttyp10:mov bx,ttvt220 ; VT220
- jmp short vsett1
- vttyp20:mov bx,ttvt320 ; VT320
- jmp short vsett1
- vttyp40:mov bx,tttek ; Tek
- jmp short vsett1
- vttyp80:mov bx,tthoney ; Honeywell VIP7809
- jmp short vsett1
- vttyp100:mov bx,ttpt200 ; Prime PT200
- jmp short vsett1
- vttyp200:mov bx,ttd463 ; Data General D463
- mov vtemu.vtchset,0 ; setup ASCII as char set in G0
- jmp short vsett1
- vttyp400:mov bx,ttd470 ; Data General D470
- mov vtemu.vtchset,0 ; setup ASCII as char set in G0
- jmp short vsett1
-
- vttype: mov ah,cmkey ; SET TERM TYPE
- xor bx,bx ; table is help
- mov dx,offset termtb ; use this table
- call comnd
- jnc vsett1 ; nc = success
- ret ; failure
-
- vsett1: mov temp,bx ; save terminal type
- mov temp2,-1 ; assume no enable/disable Tek
- cmp bx,tttek ; set term tek?
- jne vsett2 ; ne = no
- mov dx,offset disatab ; disable/enable keyword table
- xor bx,bx ; help is the table
- mov comand.cmcr,1 ; allow bare CR's
- mov ah,cmkey ; get enable/disable keyword
- call comnd
- mov comand.cmcr,0 ; no more bare CR's
- jc vsett2 ; c = no such keyword
- mov temp2,bx ; save enable/disable keyword value
- mov bx,flags.vtflg ; get current terminal type
- mov temp,bx ; and force it here
-
- vsett2: mov ah,cmeol
- call comnd ; get a confirm
- jc vsettx ; c = failure
- vsett3: mov bx,temp
- mov flags.vtflg,bx ; Set the terminal emulation type
- mov tekflg,0 ; clear graphics mode
- or vtemu.vtflgst,vscompress+vshscroll ; set compress to text-132
- or vtemu.vtflgop,vscompress+vshscroll
- ; and horz scroll to manual
- cmp bx,tttek ; adjusting Tek?
- je vsett4 ; e = yes
- test bx,ttd463+ttd470 ; DG D463/470?
- jz vsett6 ; z = no
- and vtemu.vtflgst,not (vscompress+vshscroll) ; comp = graphics,
- and vtemu.vtflgop,not (vscompress+vshscroll) ; horz scroll = auto
- vsett6: cmp temp2,-1 ; just enable/disable tek?
- je vsett5 ; e = no
- vsett4: and denyflg,not tekxflg ; enable Tek
- cmp temp2,1 ; ought we disable?
- jne vsett5 ; ne = no
- or denyflg,tekxflg ; disable Tek
- vsett5: clc ; success
- vsettx: ret
-
- vtchar: mov ah,cmkey ; Set Term character set
- xor bx,bx ; character set table for help
- mov temp,bx ; counter of trailing items
- mov dx,offset chatab ; character set table
- call comnd
- jc vtcharx ; c = failure
- mov decbuf,bl ; save here
- mov ax,word ptr vtemu.vttable ; table of 4 overrides now
- mov word ptr decbuf+1,ax ; copy them to temporary table
- mov ax,word ptr vtemu.vttable+2
- mov word ptr decbuf+3,ax
- vtchar1:mov comand.cmcr,1 ; allow bare CR's
- mov ah,cmkey
- xor bx,bx
- mov dx,offset sidetab ; read Gnumber item, if any
- call comnd
- mov comand.cmcr,0 ; no bare CR's
- jc vtchar2 ; c = no match, get confirm
- inc temp ; say have a trailing table number
- and bx,3 ; remove ASCII value encoding
- add bx,offset decbuf+1 ; address of slot to store info
- mov al,decbuf ; set ident
- mov [bx],al ; store table ident in G0..G3 slot
- jmp short vtchar1 ; repeat
-
- ; vtemu.vtchset: changed to new set if no table trailers, else intact
- ; vtemu.vttable db 4 dup(0ffh) char set numbers for G0..G3 as overrides,
- ; use 0ffh to mean no override for table Gn
- vtchar2:mov ah,cmeol ; get EOL confirmation
- call comnd
- jc vtcharx ; c = failure, quit
- mov vtemu.vtchop,-1 ; say reinit char tables
- cmp temp,0 ; trailers (skip regular setup)?
- jne vtchar3 ; ne = yes
- mov al,decbuf ; get character set
- mov vtemu.vtchset,al ; set default character set
- ; just overrides
- vtchar3:mov ax,word ptr decbuf+1 ; first pair of char set idents
- mov word ptr vtemu.vttable,ax
- mov ax,word ptr decbuf+3 ; second pair
- mov word ptr vtemu.vttable+2,ax
- clc
- vtcharx:ret
-
- vtshift:mov ah,cmkey ; Set Term Output-shift auto, none
- xor bx,bx
- mov dx,offset shifttab
- call comnd
- jc vtcharx ; c = failed
- mov flags.oshift,bl ; store result
- ret
-
- vtrollbk:mov ah,cmkey ; Set Term Roll On/Off, auto roll back
- xor bx,bx ; Use on/off table as help
- mov dx,offset ontab ; Use on/off table
- call comnd
- jc vtrollx ; c = failure
- push bx
- mov ah,cmeol ; get a confirm
- call comnd
- pop bx
- jc vtrollx ; c = failure
- mov vtroll,bl ; set roll state (0=no auto rollback)
- clc
- vtrollx:ret
-
- ; Set Term Color foreground, background
- vtcolor:mov bx,vtemu.att_ptr ; get address of attributes byte
- mov bl,[bx] ; get attributes
- mov decbuf,bl ; save in work temp
- mov al,vtclear ; screen clear state
- mov ah,refresh ; refresh state
- mov word ptr decbuf+1,ax ; save here
- call vsetcol ; get and analyze colors
- jc vtcolo1 ; c = failure
- mov al,decbuf ; get current attributes
- mov bx,vtemu.att_ptr ; get address of attributes byte
- mov [bx],al ; store attributes
- mov savattr,al ; saved emulator attributes
- mov ax,word ptr decbuf+1
- mov vtclear,al ; update these items
- mov refresh,ah
- clc
- vtcolo1:ret
- ; setup color information
- vsetcol:mov ah,cmword ; get number(s) after set term color
- mov bx,offset colhlp ; use this help
- mov dx,offset rdbuf ; temp buffer
- mov rdbuf,0 ; clear the buffer
- mov comand.cmcr,1 ; allow bare c/r's
- call comnd
- jc vsetco2 ; c = failure
- or ax,ax ; text given?
- jz vsetco1 ; z = no
- mov si,offset rdbuf ; si = place where atoi wants text
- call vsetco3 ; analyze
- jmp short vsetcol ; get more data
- vsetco1:mov ah,cmeol ; get end of line confirm
- call comnd
- vsetco2:ret ; c set if failure
-
- vsetco3:mov dx,si
- call strlen ; get count for atoi
- mov ah,cl ; count for atoi
- call atoi ; convert text to numeric in ax
- jnc vsetco3a ; got a value
- clc
- ret ; out of data
- vsetco3a:or ax,ax ; reset all? regular IBM CGA refresh
- jnz vsetco4 ; nz = no
- mov decbuf+2,0 ; Regular (slow) screen refresh
- mov decbuf,07h ; clear all, set white on black
- mov decbuf+1,2 ; set trigger for emulator clear scrn
- jmp short vsetco3
-
- vsetco4:cmp ax,1 ; high intensity?
- jne vsetco5 ; e = no
- or decbuf,08h ; set high intensity
- mov decbuf+1,1 ; set trigger for emulator keep screen
- jmp short vsetco3
-
- vsetco5:cmp ax,10 ; fast refresh?
- jne vsetco6 ; ne = no
- mov decbuf+2,1 ; Fast screen refresh
- jmp short vsetco3
-
- vsetco6:cmp ax,30 ; check range
- jb vsetco8 ; b = too small, complain
- cmp ax,37
- ja vsetco7 ; 30-37 is foreground color
- sub al,30 ; remove foreground bias
- and decbuf,not 07H ; clear foreground bits
- mov bx,ax
- mov al,colortb[bx] ; get reversed bit pattern
- or decbuf,al ; load new bits
- mov decbuf+1,2 ; set trigger for emulator clear scn
- jmp short vsetco3
-
- vsetco7:cmp ax,40
- jb vsetco8 ; b = bad value
- cmp ax,47 ; compare as unsigned
- ja vsetco8 ; 40-47 is background
- sub al,40 ; remove background bias
- and decbuf,not 70H ; clear background bits
- mov bx,ax
- mov al,colortb[bx] ; get reversed bit pattern
- mov cl,4 ; rotate 4 positions
- rol al,cl
- or decbuf,al ; load new bits
- mov decbuf+1,2 ; set trigger for emulator clear scn
- jmp vsetco3
-
- vsetco8:mov ah,prstr ; not in range - complain and exit
- mov dx,offset colerr
- int dos
- mov kstatus,ksgen ; general failure
- stc ; error
- ret
-
-
- vtgraph:mov ah,cmkey ; Set Term graphics
- xor bx,bx ; Use graphics table as help
- mov dx,offset graftab ; Use graphics table
- call comnd
- jc vtgrapx ; c = failure
- cmp bx,100h ; in the special options area?
- ja vtgrap1 ; a = yes
- push bx
- mov ah,cmeol ; get a confirm
- call comnd
- pop bx
- jc vtgrapx ; c = failure
- mov tekgraf,bl ; set Tek graphics board type
- clc
- vtgrapx:ret
- vtgrap1:cmp bx,101h ; character writing?
- jne vtgrap2 ; ne = no
- mov ah,cmkey ; Set Term graphics char-writing
- xor bx,bx ; no help
- mov dx,offset gchrtab ; opaque/transparent table
- call comnd
- jc vtgrapx ; c = failure
- push bx
- mov ah,cmeol ; get a confirm
- call comnd
- pop bx
- jc vtgrapx
- mov chcontrol,bl ; set/reset opaque char control
- clc
- ret
- vtgrap2:cmp bx,102h ; cursor on/off?
- jne vtgrap4 ; ne = no
- mov ah,cmkey ; Set Term graphics cursor on/off
- xor bx,bx ; no help
- mov dx,offset ontab ; on/off table
- call comnd
- jc vtgrapx ; c = failure
- push bx
- mov ah,cmeol ; get a confirm
- call comnd
- pop bx
- jc vtgrapx
- mov tekcursor,bl ; set Tek text cursor on/off
- clc
- ret
-
- vtgrap4:cmp bx,103h ; Color?
- jne vtgrap6 ; ne = no
- call tekgcptr ; get pointer to active Tek color pal
- mov al,[bx] ; get background attributes
- and al,7 ; discard intensity bit
- mov cl,4
- shl al,cl
- mov ah,[bx+7] ; get foreground attributes
- or al,ah
- mov decbuf,al ; setup work temp for vsetcol
- push bx ; save index
- call vsetcol ; get and analyze colors
- pop bx
- jnc vtgrap5 ; nc = ok
- ret
- vtgrap5:mov al,decbuf ; get current attributes
- mov ah,al ; get background bits
- mov cl,4
- shr ah,cl ; just background here
- and al,0fh ; just foreground here
- mov [bx],ah ; store colpal[0] as background
- mov [bx+7],al ; store colpal[7] as foreground
- clc ; success
- vtgrap6:ret
-
- vtbeep: mov ah,cmkey ; SET TERM BELL
- xor bx,bx ; use table as help
- mov dx,offset beltab ; use Bell table
- call comnd
- jc vtbeepx ; c = failure
- push bx
- mov ah,cmeol ; get a confirm
- call comnd
- pop bx
- jc vtbeepx ; c = failure
- mov belltype,bl ; set bell type
- vtbeepx:ret ; return carry clear or set
-
- ; SET TERM BYTESIZE {7-bit | 8-bit}
- vtbyte: mov ah,cmkey ; SET TERM DISPLAY {7-bit | 8-bit}
- mov dx,offset distab ; table
- xor bx,bx ; help is table
- call comnd
- jc vtbytex ; c = failure
- push bx
- mov ah,cmeol ; get a confirm
- call comnd
- pop bx
- jc vtbytex ; c = failure
- and flags.remflg,not d8bit ; clear display 8-bit bit
- or flags.remflg,bl ; set or clear the bit
- vtbytex:ret
-
- vtupss: mov ah,cmkey ; SET TERM UPSS
- mov bx,offset upsshlp ; help
- mov dx,offset upsstab ; UPSS table
- call comnd ; get UPSS char set
- jc vtupssx ; failure
- push bx
- mov ah,cmeol
- call comnd
- pop bx
- jc vtupssx ; c = fail
- mov al,96 ; assume 96 byte set
- or bh,bh ; one byte set identifier?
- jz vtupss1 ; z = yes
- mov al,94 ; a 94 byte set
- vtupss1:mov upss,al ; set length
- mov word ptr upss+1,bx ; store set ident
- mov vtemu.vtchop,-1 ; clear operational char set to reinit
- clc
- vtupssx:ret
-
- apcctl: mov ah,cmkey ; SET TERM APC-macro enable, disable
- mov bx,offset apchlp ; help
- mov dx,offset apctab ; APC table
- call comnd
- jc apcctl1 ; failure
- push bx
- mov ah,cmeol
- call comnd
- pop bx
- jc apcctl1 ; c = fail
- mov apcenable,bl ; enable flag
- clc
- apcctl1:ret
-
- vtenqctl:mov ah,cmkey ; SET TERM Answerback {ON, OFF}
- mov bx,offset enqhlp ; help
- mov dx,offset ontab ; on/off table
- call comnd
- jc vtenqctl1 ; failure
- push bx
- mov ah,cmeol
- call comnd
- pop bx
- jc vtenqctl1 ; c = fail
- mov vtenqenable,bl ; enable (1) flag
- clc
- vtenqctl1:ret
-
- scrwrite:mov ah,cmkey ; SET TERM SCREEN-WRITING
- xor bx,bx ; help
- mov dx,offset writetab ; screen table
- call comnd
- jc scrwritx ; failure
- push bx
- mov ah,cmeol
- call comnd
- pop bx
- jc vtupssx ; c = fail
- mov writemode,bl ; store writing mode
- clc
- scrwritx:ret
-
- expmemory:mov ah,cmkey ; EXPANDED-MEMORY {ON, OFF}
- mov bx,offset expmhlp ; help
- mov dx,offset ontab ; on/off table
- call comnd
- jc expmem2 ; failure
- push bx
- mov ah,cmeol
- call comnd
- pop bx
- jc expmem2 ; c = fail
- cmp useexp,bl ; changing kinds?
- je expmem1 ; e = no
- mov vsbuff_inited,0 ; say reinitialize buffer memory
- mov useexp,bl ; enable (1) flag
- expmem1:clc
- expmem2:ret
-
- vtcodepage:mov ah,cmkey ; SET TERM CODE-PAGE
- xor bx,bx ; help
- mov dx,offset setchtab ; Code Page table
- call comnd
- jc vtcode1 ; failure
- push bx
- mov ah,cmeol
- call comnd
- pop bx
- jc vtcode1 ; c = fail
- mov vtcpage,bx ; new terminal Code Page
- mov vtemu.vtchop,-1 ; force change of working set
- clc
- vtcode1:ret
-
- ; SET Term flags. These are the (near) equivalent of VT100 Setup mode values.
- flg1: mov ax,vsnewline ; NEWLINE
- mov dx,offset ontab
- jmp short flgset
- flg2: mov ax,vswrap ; WRAP
- mov dx,offset ontab
- jmp short flgset
- flg4: mov ax,vswdir ; DIRECTION
- mov dx,offset dirtab
- jmp short flgset
- flg5: mov ax,vskeyclick ; KEYCLICK
- mov dx,offset ontab
- jmp short flgset
- flg6: mov ax,vsmarginbell ; MARGIN BELL
- mov dx,offset ontab
- jmp short flgset
- flg7: mov ax,vscursor ; CURSOR
- mov dx,offset curtab
- jmp short flgset
- flg8: mov ax,vsscreen ; SCREEN
- mov dx,offset scrtab
- jmp short flgset
- flg9: mov ax,vscntl ; CONTROLS
- mov dx,offset cntltab
- jmp short flgset
- flg10: mov ax,deckpam ; KEYPAD
- mov dx,offset kpamtab
- jmp short flgset
- flg11: mov ax,decckm ; ARROW
- mov dx,offset arrtab
- jmp short flgset
- flg12: mov ax,deccol ; WIDTH
- mov dx,offset widtab
- jmp short flgset
- flg13: mov ax,vshscroll ; Horizontal scrolling
- mov dx,offset hstab
- jmp short flgset
- flg14: mov ax,vscompress ; compressed text display
- mov dx,offset cmptab
- ;; jmp short flgset
-
- flgset: push ax ; save flag
- mov ah,cmkey ; another keyword
- xor bx,bx ; use default help, dx has table ptr
- call comnd
- pop ax ; recover index
- jc flgse0 ; c = failure
- push ax
- push bx ; save result of keyword
- mov ah,cmeol ; get confirm
- call comnd
- pop bx
- pop ax ; recover flag
- jc flgse0 ; c = failure
- or bx,bx ; set or clear?
- jz flgse1 ; z = clear it
- or vtemu.vtflgst,ax ; set the flag
- or vtemu.vtflgop,ax ; in runtime flags too
- flgse3: test ax,deccol ; modifying screen width?
- jz flgse2 ; z = no
- mov al,crt_cols ; current width
- mov dos_cols,al ; width to remember, for changes
- flgse2: clc ; success
- flgse0: ret
- flgse1: not ax ; Complement
- and vtemu.vtflgst,ax ; clear the indicated setup flag
- and vtemu.vtflgop,ax ; clear the indicated runtime flag
- not ax
- jmp short flgse3 ; test for screen change
-
- ; SET Term Tabstops Clear ALL
- ; SET Term Tabstops Clear AT n1, n2, ..., nx
- ; SET Term Tabstops At n1, n2, ..., nx
-
- tabmod: mov ah,cmkey ; parse keyword
- mov bx,offset clrhlp ; help text
- mov dx,offset tabtab ; table
- call comnd
- jc tabmo2 ; c = failure
- mov clrset,2 ; 2 = code for set a tab
- or bl,bl ; clear?
- jnz tabmo4 ; nz = no, SET. parse column number(s)
- mov clrset,1 ; code for clear at/all tab(s)
- mov ah,cmkey ; CLEAR, parse ALL or AT
- mov bx,offset clrhlp ; help text
- mov dx,offset alltab ; parse ALL or AT
- call comnd
- jc tabmo2 ; c = failure
- or bx,bx ; ALL?
- jnz tabmo4 ; nz = AT, clear at specific places
- mov ah,cmeol ; confirm the ALL
- call comnd
- jc tabmo2 ; c = failure
- mov cx,vswidth ; ALL, means clear all tab stops
- tabmo1: mov dx,cx
- dec dl ; column number, starting with 0
- mov si,vtemu.vttbs ; the cold-start buffer
- call ftabclr ; clear the tab
- loop tabmo1 ; do all columns
- mov si,vtemu.vttbs
- mov di,vtemu.vttbst ; and active buffer
- call tabcpy ; update active tabs
- clc ; success
- tabmo2: ret ; a success/fail return point
-
- tabmo4: mov si,vtemu.vttbs ; from the cold-start buffer
- mov di,offset decbuf ; temp work buffer
- call tabcpy ; make a working copy of the tabs
- mov skip,0 ; clear spacing-active flag
- mov temp,0 ; place where last tab was written
- tabmo6: mov bx,offset clrhlp2 ; tell them we want a column number
- mov ah,cmword ; get line of text
- mov dx,offset rdbuf ; temp buffer
- call comnd
- jc tabmo2 ; c = failure
- or ax,ax ; anything given?
- jnz tabmo7 ; nz = yes
- mov ah,cmeol ; confirm end of line
- call comnd
- jc tabmo2 ; failure
- mov si,offset decbuf ; copy tabs from temp work buffer
- mov di,vtemu.vttbs ; to the cold-start buffer
- call tabcpy ; copy work to cold start
- mov di,vtemu.vttbst ; and terminal emulator's active buf
- call tabcpy
- clc
- ret
-
- tbsbad: mov ah,prstr ; not in range - complain
- mov dx,offset tbserr
- int dos
- stc
- ret
-
- tabmo7: mov si,offset rdbuf ; si = place where atoi wants text
- tabmo8: mov dx,si
- call strlen ; get length of this word
- jcxz tabmo6 ; empty, get more user input
- mov ah,cl ; where atoi wants length
- call atoi ; convert text to numeric in ax
- jnc tabmo9 ; nc = successful
- cmp byte ptr [si],':' ; spacing separator?
- jne tbsbad ; ne = no, no number available
- inc si ; skip colon, do start:space analysis
- inc skip ; set spacing-active flag
- jmp short tabmo8 ; get another token
-
- tabmo9: cmp skip,0 ; want spacing value now?
- jne tabmo11 ; ne = yes, go do it
- mov dx,ax ; column (1-vswidth style)
- dec dx ; put column in range 0-131
- or dx,dx ; check range (1-vswidth-->0-...)
- js tbsbad ; s = too small. complain
- cmp dl,vswidth-1 ; more than the right most column?
- ja tbsbad ; a = yes, quit
- mov temp,dx ; remember last written position
- jmp tabmo15 ; and write this member
-
- tabmo11:mov dx,temp ; continue spacing analysis
- mov skip,0 ; clear spacing-active flag
- mov cx,ax ; "space" value
- or cx,cx ; zero spacing?
- jnz tabmo12 ; nz = no
- inc cx ; don't get caught with zero spacing
- tabmo12:cmp dx,vswidth-1 ; largest tab stop
- ja tabmo8 ; a = done largest tab stop
- mov temp,dx ; remember last written tabstop
- push si
- mov si,offset decbuf ; the work buffer
- cmp clrset,2 ; set?
- jne tabmo13 ; ne = no, clear
- call ftabset ; set tabstop in column DL
- jmp short tabmo14
- tabmo13:call ftabclr ; clear tabstop in column DL
- tabmo14:add dx,cx ; new column value
- pop si
- jmp short tabmo12 ; finish spacing loop
-
- tabmo15:push si ; individual tabstop
- mov si,offset decbuf ; the work buffer
- cmp clrset,2 ; set?
- jne tabmo16 ; ne = no, clear
- call ftabset ; set tabstop in column DL
- jmp short tabmo17 ; get next command value
- tabmo16:call ftabclr ; clear tabstop in column DL
- tabmo17:pop si
- jmp tabmo8 ; get next command value
-
- tabcpy: push es ; worker copy routine
- push si
- push di
- mov cx,ds
- mov es,cx
- mov cx,(vswidth+7)/8 ; update all active tab stops
- cld
- rep movsb
- pop di
- pop si
- pop es
- clc ; success
- ret
- VTS endp ; end of Set Term things
-
- ; Terminal Status display, called within STAT0: in MSSSET
- VTSTAT proc near ; enter with di within sttbuf, save bx
- mov bx,offset vtstbl ; table of things to show
- jmp statc ; status common code, in mssset
- vtstat endp
-
- colstat proc near ; worker for colstat
- push si
- mov si,offset colst1
- cld
- colstd1:lodsb
- cmp al,'$' ; end of string?
- je colstd2 ; e = yes
- stosb
- jmp short colstd1
- colstd2:mov bx,vtemu.att_ptr ; pointer to attributes byte
- mov bl,byte ptr[bx]
- xor bh,bh
- push bx
- and bx,7 ; get foreground set
- mov al,colortb[bx] ; get reversed bit pattern
- add al,'0' ; add ascii bias
- stosb
- pop bx
- mov si,offset colst2
- colstd3:lodsb
- cmp al,'$'
- je colstd4
- stosb
- jmp short colstd3
- colstd4:mov cl,4 ; rotate 4 positions
- shr bl,cl
- and bx,7 ; get background set
- mov al,colortb[bx] ; get reversed bit pattern
- add al,'0' ; add ascii bias
- stosb
- pop si
- ret
- colstat endp
-
- tabstat proc near ; worker,display tabs ruler for Status
- push dx
- cld
- mov al,cr
- stosb
- cmp cl,10 ; are we on a new line?
- jb tabsta0 ; b = no, do a lf now
- mov al,lf
- stosb
- tabsta0:xor cl,cl ; column index
- xor ax,ax ; ah = tens, al = units counter
- tabsta1:mov dl,'.' ; default position symbol
- inc al
- cmp al,10 ; time to roll over?
- jb tabsta2 ; b = not yet
- xor al,al ; modulo 10
- inc ah
- mov dl,ah ; display a tens-digit
- add dl,'0'
- cmp dl,'9' ; larger than 90?
- jbe tabsta2 ; be = no
- sub dl,10 ; roll over to 0, 1, etc
- tabsta2:push dx
- push si
- mov dl,cl ; column number, counted from 0
- mov si,vtemu.vttbst ; the active buffer
- call istabs ; is tab set here?
- pop si
- pop dx
- jnc tabsta3 ; nc = no
- mov dl,'T' ; yes, display a 'T'
- tabsta3:push ax
- mov al,dl
- stosb
- pop ax
- inc cl
- cmp cl,byte ptr low_rgt ; done yet?
- jb tabsta1 ; b = not yet
- pop dx
- ret
- tabstat endp
-
- ; Returns carry set if column in DL is a tab stop, else carry clear.
- ; Enter with column number in DL (starts at column 0, max of vswidth-1)
- ; and tabstop buffer offset in SI.
- istabs proc near
- push bx
- push cx
- mov cl,dl ; column number (0 to swidth-1)
- and cl,00000111b ; keep bit in byte (0-7)
- inc cl ; map to 1-8
- mov bl,dl ; column
- shr bl,1 ; bl / 8 to get byte
- shr bl,1
- shr bl,1
- xor bh,bh ; clear high byte
- mov bl,[si+bx] ; get a byte of tab bits
- ror bl,cl ; rotate to put tab-set bit into carry
- pop cx
- pop bx
- ret
- istabs endp
-
- filler proc near ; use space
- mov cx,20
- mov al,' '
- cld
- rep stosb
- ret
- filler endp
-
- ; Jump here to exit Connect mode and execute macros 'KEYBOARDR' (vtkrmac) or
- ; 'KEYBOARDS' (vtksmac). Does nothing if macro does not exist.
- ; Preserves registers except ax. Returns to TELNET caller with 'C' in kbdflg.
- vtkrmac proc near ; RESET macro
- mov vtmacname,offset vtkrname ; select macro name
- mov vtmaclen,vtkrlen ; and its length
- call dword ptr vtmacroptr ; FAR pointer, finish in common code
- jc vtkrmac1 ; c = failure
- jmp far ptr endcon ; end connect mode, do macro
- vtkrmac1:ret
- vtkrmac endp
-
- vtksmac proc near ; SET macro
- mov vtmacname,offset vtksname
- mov vtmaclen,vtkslen
- call dword ptr vtmacroptr ; FAR pointer
- jc vtksmac1 ; c = failure
- jmp far ptr endcon ; end connect mode, do macro
- vtksmac1:ret
- vtksmac endp
-
- ; Invoked by keyboard translator when an unknown keyboard verb is used as
- ; a string definition, such as {\ktest}. Enter with vtmacname pointing to
- ; uppercased verb name, asciiz, and vtmaclen set to its length.
- extmacro proc near
- call dword ptr vtmacroptr ; FAR pointer
- jc extmac1 ; c = failure
- jmp far ptr endcon ; end connect mode, do macro
- extmac1:ret
- extmacro endp
-
- ; Invokes macro PRODUCT with variables \%1..\%9
- ; defined as the ascii renditions of the control sequence numeric paramters
- ; param[0]..param[8], and sets script ARGC item to one greater than this.
-
- product proc near
- call far ptr prodwork ; FAR pointer
- jc prodmac1 ; c = failure
- jmp far ptr endcon ; end connect mode, do macro
- prodmac1:ret
- product endp
-
- ; support for vtmacro and fproduct
- fdec2di proc far
- call dec2di
- ret
- fdec2di endp
-
- term proc near
- call far ptr fterm
- ret
- term endp
-
- fclrmod proc far
- call clrmod
- ret
- fclrmod endp
-
- fputmod proc far
- call putmod
- ret
- fputmod endp
-
- fcmblnk proc far
- call cmblnk
- ret
- fcmblnk endp
- fkbhold proc far
- call kbhold
- ret
- fkbhold endp
- fisfile proc far
- call isfile
- ret
- fisfile endp
- fprtchr proc far
- call prtchr
- ret
- fprtchr endp
- fkeybd proc far
- call keybd
- ret
- fkeybd endp
- fpntflsh proc far
- call pntflsh
- ret
- fpntflsh endp
- fpntchr proc far
- call pntchr
- ret
- fpntchr endp
- foutchr proc far
- call outchr
- ret
- foutchr endp
- fpcwait proc far
- call pcwait
- ret
- fpcwait endp
- fstrcpy proc far
- call strcpy
- ret
- fstrcpy endp
- fspath proc far
- call spath
- ret
- fspath endp
- fcrun proc far
- call crun
- ret
- fcrun endp
- fserini proc far
- call serini
- ret
- fserini endp
- vtinit proc near
- call fvtinit
- ret
- vtinit endp
-
- rtone proc near
- call frtone
- ret
- rtone endp
-
- rtpage proc near
- call frtpage
- ret
- rtpage endp
-
- lfone proc near
- call flfone
- ret
- lfone endp
-
- lfpage proc near
- call flfpage
- ret
- lfpage endp
-
- homwnd proc near
- call fhomwnd
- ret
- homwnd endp
- endwnd proc near
- call fendwnd
- ret
- endwnd endp
- dnwpg proc near
- call fdnwpg
- ret
- dnwpg endp
- dnone proc near
- call fdnone
- ret
- dnone endp
- upwpg proc near
- call fupwpg
- ret
- upwpg endp
- upone proc near
- call fupone
- ret
- upone endp
- fcptchr proc far
- call cptchr
- ret
- fcptchr endp
- fserrst proc far
- call serrst
- ret
- fserrst endp
- code ends
-
- code1 segment
- assume cs:code1
- ; Kermit startup time initialization
- flclyini proc far
- mov ah,conout ; write a space to determine
- mov dl,' ' ; DOS's default cursor coloring
- int dos
- call getpcur ; get current cursor position into dx
- mov lincur,cx ; save cursor type (scan line #'s)
- dec dl ; backup to last char
- or dl,dl
- jns lclyin5 ; ns = no problem
- xor dl,dl ; else set cursor back to left margin
- lclyin5:call setpcur ; set the cursor
- call getpcha ; read current attributes into AH
- mov scbattr,ah ; save video attributes
- mov savattr,ah ; and saved attributes
- mov dosattr,ah ; and here too
- and ah,att_bold ; select intensity bit
- mov userbold,ah ; save bit for user Bold control
- mov ega_mode,0 ; assume no EGA
- mov ax,1200H ; EGA: Bios alternate select
- mov bl,10H ; Ask for EGA info
- mov bh,0ffH ; Bad info, for testing
- mov cl,0fH ; Reserved switch settings
- int screen ; EGA, are you there?
- cmp cl,0cH ; Test reserved switch settings
- jge lclyin1 ; ge = no EGA in use
- push es
- mov ax,40h ; check Bios 40:87h for ega being
- mov es,ax ; the active display adapter
- test byte ptr es:[87h],8 ; is ega active?
- pop es
- jnz lclyin1 ; nz = no
- mov ega_mode,1 ; yes, set flag to say so
- mov crt_norm,3 ; assume color monitor is attached
- or bh,bh ; is color mode in effect?
- jz lclyin1 ; z = yes
- mov crt_norm,7 ; else use mode 7 for mono
- lclyin1:call scrseg ; test running in an Environment
- call dvtest ; test for running under DESQview
- call scrmod ; read video state, get crt_mode
- mov cursor,0 ; initial cursor
- mov dosetcursor,-1 ; cursor position reminder, none
- mov ax,low_rgt ; lower right corner of screen
- mov al,crt_mode
- mov crt_norm,al ; save as normal mode
- mov ah,crt_cols
- mov dos_cols,ah ; remember for exiting Connect mode
- call vsalloc ; allocate memory for virtual screen
- jnc lclyin4 ; nc = success
- mov ah,prstr
- mov dx,offset memerr ; say not enough memory to operate
- int dos
- mov flags.extflg,1 ; set Kermit exit flag
- ret
-
- lclyin4:call vsinit ; init terminal emulator module MSZ
- mov bx,vtemu.att_ptr ; attributes pointer
- mov ah,dosattr ; startup video attributes
- and ah,not att_bold ; emulation intensity to normal
- or ah,userbold
- mov [bx],ah ; set initial emulation attributes
- and vtemu.vtflgst,not deccol ; assume 80 column screen
- and vtemu.vtflgop,not deccol
- cmp crt_cols,80 ; screen cols now, wide screen?
- jbe lclyin6 ; be = no
- or vtemu.vtflgst,deccol ; say using 132 columns screen
- or vtemu.vtflgop,deccol
- lclyin6:ret
- flclyini endp
-
- ; Allocate memory for virtual screen buffers vscreen and vsat.
- ; Return carry clear if success, else carry set. Removes older allocations.
- vsalloc proc near
- call vsalloc4 ; free alloc'd memory, if any
- mov al,crt_lins ; one minus number of screen rows
- inc al
- mov cl,vswidth ; virtual screen vscreen
- mul cl ; lines time width, words for vscreen
- add ax,ax ; need words
- add ax,15 ; round up
- mov cl,4 ; convert to paragraphs
- shr ax,cl ; need words rather than bytes
- mov cx,ax ; save total wanted paragraphs in cx
- mov bx,ax ; ask for the memory
- mov ah,alloc ; allocate memory
- int dos ; bx has # free paragraphs
- mov word ptr vs_ptr+2,ax ; seg of vsscreen (offset is zero)
- cmp cx,bx ; got what we wanted
- jb vsalloc5 ; b = no
- push es
- mov es,ax
- xor di,di
- shl cx,1
- shl cx,1
- shl cx,1 ; paragraphs to words
- mov ah,scbattr
- mov al,' '
- cld
- rep stosw ; clear the memory with def colors
- pop es
- mov al,crt_lins
- inc al ; attributes (nibbles)
- mov cl,(vswidth+1)/2 ; lines time width, bytes for vsattr
- mul cl
- add ax,15 ; round up
- mov cl,4 ; convert to paragraphs
- shr ax,cl
- mov cx,ax ; save total wanted paragraphs in cx
- mov bx,ax ; ask for the memory
- mov ah,alloc ; allocate the memory
- int dos ; bx has # free paragraphs
- mov word ptr vsat_ptr+2,ax ; seg of vsattr (offset is zero)
- cmp cx,bx ; got what we wanted
- jb vsalloc4 ; b = no
- push es
- mov es,ax
- xor di,di
- shl cx,1
- shl cx,1
- shl cx,1
- shl cx,1 ; paragraphs to bytes
- xor al,al
- rep stosb ; clear the memory with def extattr
- pop es
- clc ; report success
- ret
-
- vsalloc4:mov ax,word ptr vsat_ptr+2 ; seg of vsattr (offset is zero)
- or ax,ax ; unused?
- jz vsalloc5 ; z = yes
- push es
- mov es,ax ; allocated segment
- mov ah,freemem ; free it
- int dos
- mov word ptr vsat_ptr+2,0 ; clear pointer too
- pop es
- vsalloc5:mov ax,word ptr vs_ptr+2 ; seg of vsscreen
- or ax,ax ; unused?
- jz vsalloc6 ; z = yes
- push es
- mov es,ax ; allocated segment
- mov ah,freemem ; free it
- int dos
- mov word ptr vs_ptr+2,0 ; clear pointer too
- pop es
- vsalloc6:stc ; return failure
- ret
- vsalloc endp
-
- ; Allocate memory for screen rollback buffers.
- ; Return carry clear if success, else carry set to exit.
- vsbuff proc near ; screen roll back buffers
- cmp vsbuff_inited,0 ; inited yet?
- je vsbuff0 ; e = no
- clc ; say success
- ret
- vsbuff0:mov vsbuff_inited,1 ; say we are initializing
- cmp emsrbhandle,-1 ; valide EMS rollback handle?
- je vsbuff20 ; e = no
- mov ah,emsrelease ; release pages
- mov dx,emsrbhandle ; handle
- int emsint
- mov emsrbhandle,-1 ; invalidate EMS rollback handle
- mov iniseg,0 ; and no segment for page frame
- jmp short vsbuff21
- vsbuff20:mov ax,iniseg ; memory segment, window area
- or ax,ax ; anything allocated?
- jz vsbuff21 ; z = no
- mov es,ax
- mov ah,freemem ; free regular memory segment
- int dos
- mov iniseg,0
- vsbuff21:
- mov bx,rollwidth ; columns to roll back
- or bx,bx ; user override given?
- jnz vsbuff1 ; nz = yes, else physical screen
- mov bl,crt_cols ; physical screen
- xor bh,bh
- mov rollwidth,bx ; set final roll width
- vsbuff1:add bx,7 ; round up (cancel common times twos)
- mov cl,3
- shr bx,cl ; bytes/line to paragraphs/line
- mov ppl,bx ; paragraphs/line
- ; expanded memory
- cmp useexp,0 ; use expanded memory?
- je vsbuff5 ; e = no
- mov ax,sp ; do push sp test for XT vs AT/386
- push sp ; XT pushes sp-2, AT's push old sp
- pop cx ; recover pushed value, clean stack
- xor ax,cx ; same?
- jne vsbuff5 ; ne = no, XT. Don't do Int 2fh
- mov ax,xmspresent ; XMS presence test
- int 2fh
- cmp al,80h ; present?
- jne vsbuff5 ; ne = no
- mov ah,getintv ; get interrupt vector
- mov al,emsint ; EMS interrupt 67h
- int dos ; to es:bx
- mov ax,es
- or ax,bx ; check for null
- jz vsbuff5 ; z = interrupt not activated
- mov ah,emsmgrstat ; LIM 3.2 manager status
- int emsint
- or ah,ah ; ok?
- jnz vsbuff5 ; nz = not ok
- mov ax,1024 ; 1024 paragraphs per ems 16KB page
- xor dx,dx
- div ppl ; divide by paragraphs per line
- mov lineems,ax ; lines per ems page, remember
- mov al,crt_lins ; lines-1 per physical screen
- xor ah,ah
- mov cx,npages ; number of roll back screens wanted
- inc cx ; include current screen
- mul cx ; times number screens
- div lineems ; lines total / (lines/emspage)
- or dx,dx ; remainder?
- jz vsbuff2 ; z = no
- inc ax ; add page for fraction
- vsbuff2:push ax ; ax is number of emspages
- mov ah,emsgetnpgs ; get number pages free
- int emsint ; to bx
- pop ax
- or bx,bx ; any pages free?
- jz vsbuff5 ; z = no, use regular memory
- cmp bx,ax ; enough?
- jb vsbuff3 ; b = less, use what we can get
- mov bx,ax ; number of pages wanted
- vsbuff3:mov ah,emsalloc ; allocate bx pages
- int emsint
- or ah,ah ; successful?
- jnz vsbuff5 ; nz = no, failure
- mov emsrbhandle,dx ; returned handle
- mov ax,bx ; pages allocated
- mov inipara,ax ; save for later resizing of buffers
- mov ah,emsgetseg ; get segment of page frame
- int emsint ; to bx
- mov iniseg,bx ; save here
- mov ah,emsgetver ; get EMS version number
- int emsint ; to al (high=major, low=minor)
- cmp al,40h ; at least LIM 4.0?
- jb vsbuff4 ; b = no, so no name for our area
- mov si,offset emsrollname ; point to name for rollback area
- mov di,offset emsrollname+6 ; add digits
- mov dx,emsrbhandle
- mov ax,dx
- call fdec2di ; write to handle name
- mov ax,emssetname ; set name for handle from ds:si
- int emsint
- vsbuff4:jmp short vsbuff9
- ; no ems, so use regular memory
- vsbuff5:mov useexp,0 ; say no ems
- mov bx,0ffffh ; ask for all of memory, to get size
- mov ah,alloc ; allocate all of memory (must fail)
- int dos ; bx has # free paragraphs
- mov ax,bx ; ax has copy of number free paragraphs
- sub bx,26000D/16 ; space for Command.com copy #2
- jc vsbuff7 ; c = not enough for it
- mov ax,ppl ; paragraphs / line
- mul crt_lins ; times lines-1 on physical screen
- cmp bx,ax ; minimum roll back space left over?
- jbe vsbuff7 ; be = not even that much
- mov cx,npages ; number of roll back screens wanted
- inc cx ; include current screen
- mul cx ; total number of paragraphs wanted
- mov cx,ax ; save in cx
- or dx,dx ; want more than 1 MB of real memory?
- jz vsbuff6 ; e = no
- mov cx,0ffffh ; set all of real memory
- vsbuff6:cmp bx,cx ; got vs wanted paras for roll back
- jbe vsbuff8 ; be = enough but not more than needed
- mov bx,cx ; limit to our actual needs
- jmp short vsbuff8 ; ask for all we really want
- vsbuff7:xor bx,bx ; use no space at all
- mov cx,bx ; remember this new request
- vsbuff8:mov ah,alloc
- int dos
- mov iniseg,ax ; (BDT) memory segment, window area
- mov inipara,bx ; save for later resizing of buffers
- cmp cx,bx ; paragraphs wanted vs delivered
- jae vsbuff9 ; ae = enough
- mov ah,prstr
- mov dx,offset memerr ; say not enough memory to operate
- int dos
- stc ; carry set = fail
- ret
- vsbuff9:call bufadj ; set roll back buffer parameters
- clc ; carry clear for success
- ret
- vsbuff endp
-
- scrini proc far ; init screen stuff
- mov al,crt_lins ; screen lines - 1
- mov ah,crt_mode ; preserve this too
- push ax ; save
- call scrmod ; get screen mode now
- mov ax,100h ; assume 80 column mode, no-renter
- test vtemu.vtflgop,deccol ; supposed to be in 80 col?
- jz scrin5 ; z = yes
- inc al ; say want 132 cols
- scrin5: call chgdsp ; set to 80/132 columns
- call scrmod ; get crt_lins again
- pop ax
- mov crt_mode,ah ; restore in case in graphics now
- cmp al,crt_lins ; changed?
- je scrin2 ; e = no
- mov vtinited,0 ; say must reinit emulator
- mov cursor,0
- call vsalloc ; reallocate virtual screen
- jnc scrin2 ; nc = success
- mov ah,prstr
- mov dx,offset memerr ; say not enough memory to operate
- int dos
- mov sp,oldsp
- ret ; must be Far return
-
- scrin2: mov ega_mode,0 ; assume no EGA
- mov ax,1200H ; EGA: Bios alternate select
- mov bl,10H ; Ask for EGA info
- mov bh,0ffH ; Bad info, for testing
- mov cl,0fH ; Reserved switch settings
- int screen ; EGA, are you there?
- cmp cl,0cH ; Test reserved switch settings
- jge scrin1 ; ge = no EGA in use
- push es
- mov ax,40h ; check Bios 40:87h for ega being
- mov es,ax ; the active display adapter
- test byte ptr es:[87h],8 ; is ega active?
- pop es
- jnz scrin1 ; nz = no
- mov ega_mode,1 ; yes, set flag to say so
- mov crt_norm,3 ; assume color monitor is attached
- or bh,bh ; is color mode in effect?
- jz scrin1 ; z = yes
- mov crt_norm,7 ; else use mode 7 for mono
- scrin1: mov bx,vtemu.att_ptr ; attributes pointer
- mov ah,[bx]
- and ah,att_bold
- mov userbold,ah ; remember old bold
- mov ah,savattr ; saved emulator attributes
- mov scbattr,ah ; restore active value
- call scrseg ; update screen segment tv_seg(s/o)
- call getpcur ; get cursor position DX and type CX
- cmp flags.vtflg,0 ; emulating anything?
- jne scrin4 ; ne = yes
- mov cursor,dx ; use physical cursor
- scrin4: mov dx,cursor ; use old cursor, if any
- call setpos ; set cursor position
- cmp vtinited,inited ; inited emulator yet?
- je scrin11 ; e = yes, do reinit
- call fvtinit ; init it now
- call repaint ; repaint screen
- ret
-
- scrin11:cmp flags.vtflg,tttek ; Tek mode?
- je scrin12 ; e = yes
- ;; test tekflg,tek_tek+tek_dec ; Tek submode?
- ;; jz scrin14 ; z = no
- cmp tekflg,tek_tek+tek_dec ; Tek submode?
- jne scrin14 ; ne = no
- scrin12:call tekini ; init graphics mode
- ret
-
- scrin14:call ansrei ; reinit the emulator
- call repaint ; restore screen from vscreen
- scrin15:ret
- scrini endp
-
- ; Initialize terminal emulators
- fvtinit proc far
- mov ax,apcstring ; seg of apcmacro memory area
- or ax,ax ; empty?
- jz vtini4 ; z = yes
- mov es,ax
- mov ah,freemem
- int dos ; free that memory
- mov apcstring,0
- vtini4: mov holdscr,0 ; clear holdscreen
- mov vtclear,0 ; clear clear-screen indicator
- call fkbhold ; tell DEC LK250 the state, in msuibm
- or vtinited,inited
- mov ax,vtemu.vtflgst ; Setup flags
- mov vtemu.vtflgop,ax ; to operational
- mov dosetcursor,0 ; cursor position reminder, none
- mov bx,portval
- mov dl,[bx].ecoflg ; local echo flag
- and yflags,not lclecho
- or yflags,dl
- mov bx,argadr ; address of argument block
- mov dl,[bx].baudb ; baud rate code in dl
- mov dh,[bx].parity ; parity code in bits
- mov cl,4 ; 0-3 of dh
- shl dh,cl
- or dh,07H ; just say 7 data bits
- test flags.remflg,d8bit ; eight bit display?
- jz vtini1 ; z = no
- inc dh ; set low four bits to value 8
- vtini1: cmp flags.vtflg,0 ; doing emulation?
- je vtini3 ; e = no
- cmp tekflg,tek_active+tek_tek ; Tek graphics mode?
- je vtini2 ; e = yes, do it's reinit
- cmp tekflg,tek_active+tek_dec ; Tek graphics submode?
- je vtini2 ; e = yes, do it's reinit
- xor ax,ax ; assume 80 col mode (al=0)
- test vtemu.vtflgst,deccol ; want wide display?
- jz vtini1a ; z = no
- inc al ; set AL to 1 for set 132 col mode
- vtini1a:call chgdsp ; set screen width
- call ansini ; call startup routine in mszibm
- cmp flags.vtflg,tttek ; full Tek mode?
- jne vtinix ; ne = no
- or tekflg,tek_tek ; say tek mode
- jmp short vtini2 ; e = yes
- vtinix: clc
- ret
- vtini2: call tekrint ; reinitialize Tek emulator
- clc
- ret
- vtini3: call fcmblnk ; clear the screen
- clc
- ret
- fvtinit endp
-
- argini proc near ; read passed arguments
- mov bx,argadr ; base of argument block
- mov al,[bx].flgs ; get flags
- and al,capt+emheath+trnctl+lclecho+modoff
- mov yflags,al ; mask for allowable and save
- mov al,[bx].prt
- mov portno,al ; update port number
- ret
- argini endp
-
- fterm proc FAR ; terminal mode entry point
- mov argadr,ax ; save argument ptr
- mov oldsp,sp ; remember stack for i/o failure,
- mov apctrap,0 ; un-trap certain commands
- cmp flags.comflg,'t' ; doing internal Telnet?
- jne fterm2 ; ne = not Telnet
- cmp termlatch,0 ; have we been here for macro?
- jne fterm2 ; ne = yes, reset it and skip macro
- mov termlatch,1 ; arm reentry bypass
- mov bx,sescur ; get session to bl
- call vtsesmac ; this returns us to the Kermit prompt
- jc fterm2 ; c = no such macro
- fterm1: call fserrst ; shut down serial port now
- mov kbdflg,'C' ; say exit Connect mode
- ret ; return, to process macro
-
- fterm2: mov termlatch,0 ; disable bypass, enable macro again
- mov handhsc,0 ; cancel hand scrolling
- call vsbuff ; allocate screen buffer memory
- jc fterm1 ; c = failure, quit now
- call argini ; init options from arg address
- mov inemulator,1 ; say in terminal emulator (local)
- call scrini ; call screen setup
- mov grab,0 ; clear Compose/Spcl output grabber
- or kbcodes,80h ; set need-to-init flg for kbd xtlator
- mov fairprn,0 ; set printer buffer flush counter
- lp: call fprtchr ; char at port?
- jnc short lpinp ; nc = yes, go handle
- cmp tekflg,tek_active+tek_sg ; special graphics active?
- jne lpcross ; ne = no, stay in idle loop
- mov dx,dosetcursor ; preserved cursor position
- cmp dx,-1 ; should we set the cursor?
- je lpcursor ; e = no
- call teksetcursor ; set the cursor at dx
- mov dosetcursor,-1 ; turn off reminder
-
- lpcursor:test flags.vtflg,ttd463+ttd470 ; doing DG D463/D470 emulation?
- jz lpcross ; z = not DG
- cmp dgcross,0 ; is DG crosshair active?
- je lpcross ; e = no
- xor al,al ; feed it a null command, to do mouse
- call croshair ; call Tek crosshair to read mouse
- lpcross:push bx
- mov bx,portval ; port structure address
- cmp [bx].portrdy,0 ; is port ready for business?
- pop bx
- jne lpkbd ; ne = ready
- jmp quit ; end the communications now
- lpkbd: mov fairness,0 ; say kbd was examined
- call dvpause ; tell DESQview we are not busy
- inc fairprn ; inc printer dump counter
- cmp fairprn,100 ; been here enough times now?
- jb lpkbd1 ; b = no
- call fpntflsh ; flush printer buffer
- jnc lpkbd0 ; nc = success
- call pntdead ; call bad printer notifier
- lpkbd0: mov fairprn,0 ; reset for next time
- lpkbd1: call fkeybd ; call keyboard translator in msu
- jc quit ; carry set = quit connect mode
- jmp short lp ; and repeat idle loop
-
- lpinp: and al,parmsk ; apply 8/7 bit parity mask
- call outtty ; print on terminal
- inc fairness ; say read port but not kbd, again
- cmp fairness,100 ; this many port reads before kbd?
- jb lp ; b = no, read port again
- jmp short lpkbd ; yes, let user have a chance too
-
- quit: mov sp,oldsp ; recover startup stack pointer
- ; TERM caller's return address is now
- ; on the top of stack. A longjmp.
- mov ah,scbattr ; current emulator attributes
- mov savattr,ah ; save them here
- call fpntflsh ; flush printer buffer
- call tekend ; cleanup Tektronix mode
-
- mov inemulator,0 ; say not in terminal emulator (local)
- mov al,1
- call csrtype ; turn on underline cursor
- mov ah,dosattr ; attributes at init time
- mov scbattr,ah ; background = original state
- call fclrmod ; clear mode line with DOS attributes
- mov ax,100h ; assume using 80 col screen
- cmp dos_cols,80 ; startup screen width
- jbe quit1 ; be = assume 80 columns
- inc al ; say do 132 columns
- quit1:
- push vtemu.vtflgop
- or vtemu.vtflgop,vscompress ; turn off compressed mode
- call chgdsp ; reset display width to startup
- pop vtemu.vtflgop
- call scrmod ; update size info
- ; for ega in non-standard # lines
- test tv_mode,10h ; DV active?
- jnz quit2 ; nz = yes, it messes with the cursor
- cmp ega_mode,0 ; ega board active?
- je quit2 ; e = no
- cmp byte ptr low_rgt+1,23 ; is screen standard length?
- je quit2 ; e = yes, so regular cursor set is ok
- push es ; turn off ega cursor emulation
- mov ax,40h ; byte 40:87H is ega Info byte
- mov es,ax
- push es:[87h] ; save info byte around call
- or byte ptr es:[87h],1 ; set emulation off (low bit = 1)
- mov cx,lincur ; cursor shape to set
- mov ah,1 ; set the shape
- int screen ; back to starting value
- pop es:[87h] ; recover original Info byte
- pop es ; and our work reg
- jmp short quit3 ; skip regular mode cursor setting
- quit2: ; for regular sized screen
- mov cx,lincur ; cursor type at startup
- mov ah,1
- int screen ; restore cursor type
- quit3: mov dh,byte ptr low_rgt+1 ; bottom line -1
- xor dl,dl ; left most column
- call setpcur ; set cursor physical position
- mov al,yflags
- mov bx,argadr
- mov [bx].flgs,al ; update flags in arg block
- call dvpause ; tell DESQview we are not busy
- ret
- fterm endp
-
- ; put the character in al to the screen
- outtty proc near
- test flags.remflg,d8bit ; keep 8 bits for displays?
- jnz outtt1 ; nz = yes, 8 bits if possible
- and al,7fh ; remove high bit
- outtt1: cmp flags.vtflg,0 ; emulating a terminal?
- je outnp10 ; e = no
- cmp vtroll,0 ; auto roll back allowed?
- je outem1 ; e = no, leave screen as is
- test tekflg,tek_active ; Tek mode active?
- jnz outem1 ; nz = yes, skip screen rolling
- push ax ; (BDT) save this for a tad
- mov ax,linec ; (BDT) are we at the buffer end?
- cmp ax,lcnt
- pop ax ; (BDT) restore the register
- je outem1 ; (BDT) e = yes
- push ax ; (BDT) save AX again
- call fendwnd ; do END to roll screen to end of buf
- pop ax ; (BDT) restore the register
- outem1: test tekflg,tek_active ; graphics mode active?
- jz outem2 ; z = no
- test tekflg,tek_tek+tek_dec ; Tek submode active for input?
- jnz outem3 ; nz = yes, use Tek emulator
- outem2: call anstty ; call terminal emulator, char in AL
- ret
- outem3: call tekemu ; use Tek emulator and return
- ret
- ; use DOS for screen output
- outnp10:test flags.remflg,d8bit ; keep 8 bits for displays?
- jnz outnp9 ; nz = yes, 8 bits if possible
- and al,7fh ; remove high bit
- outnp9: cmp rxtable+256,0 ; translation turned off?
- je outnp7 ; e = yes, no translation
- push bx
- mov bx,offset rxtable ; address of translate table
- xlatb ; new char is in al
- pop bx
- outnp7: test anspflg,prtscr ; should we be printing?
- jz outnp8 ; no, keep going
- call fpntchr ; queue char for printer
- jnc outnp8 ; nc = successful print
- push ax
- call vtbell ; else make a noise and
- call ftrnprs ; turn off printing
- pop ax
- outnp8: test yflags,capt ; capturing output?
- jz outnp6 ; no, forget this part
- call fcptchr ; give it captured character
- outnp6: test yflags,trnctl ; debug? if so use Bios tty mode
- jz outnp4 ; z = no
- mov ah,conout ; DOS screen write
- cmp al,7fh ; Ascii Del char or greater?
- jb outnp1 ; b = no
- je outnp0 ; e = Del char
- push ax ; save the char
- mov dl,7eh ; output a tilde for 8th bit
- int dos
- pop ax ; restore char
- and al,7fh ; strip high bit
- outnp0: cmp al,7fh ; is char now a DEL?
- jne outnp1 ; ne = no
- and al,3fH ; strip next highest bit (Del --> '?')
- jmp outnp2 ; send, preceded by caret
- outnp1: cmp al,' ' ; control char?
- jae outnp3 ; ae = no
- add al,'A'-1 ; make visible
- outnp2: push ax ; save char
- mov dl,5eh ; caret
- int dos ; display it
- pop ax ; recover the non-printable char
- outnp3: push ax
- mov dl,al
- int dos
- pop ax
- ret
- outnp4: cmp al,bell ; bell (Control G)?
- jne outnp5 ; ne = no
- jmp vtbell ; use short beep, avoid char loss
- outnp5: mov dl,al ; write without intervention
- mov ah,conout
- int dos ; else let dos display char
- ret
- outtty endp
-
- ;[IU2] Here to output an unsigned 8-bit number (in al) to the port
- ; Used by terminal emulator escape sequence output.
-
- prtnout proc near
- jmp short prtno2 ; ensure at least a zero
-
- prtno1: or al,al
- jnz prtno2 ; nz = yes, do more digits
- ret ; no, return from recursive call
- prtno2: xor ah,ah ; clear previous remainder
- mov bl,10 ; output in base 10
- div bl ; divide off a digit
- push ax ; push remainder (in ah) on stack
- call prtno1 ; recurse
- pop ax ; pop off a digit
- add ah,'0' ; make it ASCII
- mov al,ah ; send to port, in ah
- call outprt
- jc prtno3 ; failure, end connection
- ret
- prtno3: jmp far ptr endcon
- prtnout endp
-
- ; Send the character in al out to the serial port; handle echoing.
- ; Can send an 8 bit char while displaying only 7 bits locally.
- outprt proc near
- mov ah,1 ; say local echo is permitted
- jmp short outprt0
-
- prtbout:xor ah,ah ; no local echo
-
- outprt0:cmp grab,0 ; grabbing output?
- je outprt0a ; e = no
- call fgrabber ; yes, give it to the guy
- ret
- outprt0a:test al,80h ; high bit set?
- jz outpr2 ; z = no
- test flags.vtflg,ttd463+ttd470 ; Data General?
- jz outprt4 ; z = no
- test flags.remflg,d8bit ; chop DG high bit?
- jnz outpr2 ; nz = no, send as-is
- and al,7fh ; chop high bit
- jmp short outpr1 ; send with possible DG SI/SO brackets
-
- outprt4:cmp al,0a0h ; C1 area?
- jae outpr1 ; ae = no
- test vtemu.vtflgop,vscntl ; sending 8-bit controls?
- jz outprt5 ; z = no, force use of 7-bit controls
- cmp parmsk,7fh ; using parity?
- jne outpr2 ; ne = no, no need to force on that
- outprt5:push ax ; save char
- mov al,Escape ; C1 as ESCAPE <char-40h>
- call outpr2 ; send ESCAPE
- pop ax ; recover char
- sub al,40h ; relocate the code
- jmp short outpr2 ; send the char
- ; GRight printable characters
- outpr1: cmp flags.vtflg,ttgenrc ; doing term type of NONE?
- je outpr2 ; e = yes, no tables (maybe SO/SI?)
- cmp parmsk,7fh ; using parity?
- jne outpr2 ; ne = no, no shifts needed
- cmp flags.oshift,0 ; allowing shifts on output?
- je outpr2 ; e = no
- and al,not 80h ; strip high bit
- test flags.oshift,8 ; Auto?
- jnz outpr1a ; nz = yes
- test flags.oshift,1 ; force SI/SO?
- jnz outpr8 ; nz = yes
- jmp short outpr1b ; else SS2/SS3
- outpr1a:cmp GRptr,offset G1set ; GR points to G1 char set?
- je outpr8 ; e = yes, use SO/char/SI
- outpr1b:push ax ; save char
- mov al,Escape ; send SS2 as ESC N
- call outpr2 ; ESC N is Single Shift 2
- mov al,'N'
- cmp flags.oshift,4 ; force SS3?
- jb outpr7 ; b = force SS2
- je outpr1c ; e = force SS3
- cmp GRptr,offset G2set ; GR points to G2 char set?
- je outpr7 ; e = yes, else use SS3 (ESC P)
- outpr1c:inc al ; use ESC P for Single Shift 3
- outpr7: call outpr2
- pop ax ; recover char
- jmp short outpr2
-
- outpr8: push ax ; save char
- mov al,SOchar ; SO locking shift 1 for G1 to GL
- cmp flags.vtflg,ttd463+ttd470 ; D463/D470?
- jz outpr8a ; z = no
- mov al,DGescape ; send SO as DG's RS N
- call outpr2
- mov al,'N'
- outpr8a:call outpr2 ; send it
- pop ax
- push ax ; preserve ah around call
- call outpr2 ; send real character (7 bit'd)
- pop ax
- mov al,SIchar ; shift back to normal
- test flags.vtflg,ttd463+ttd470 ; D463/D470?
- jz outpr2 ; z = no
- mov al,DGescape ; send SI as DG's RS O
- call outpr2
- mov al,'O'
-
- outpr2: or ah,ah ; local echo permitted?
- jz outpr3 ; z = no
- test yflags,lclecho ; echoing?
- jz outpr3 ; z = no, forget it
- push ax ; save char
- call outtty ; display it
- pop ax ; restore
- cmp flags.comflg,'t' ; doing Telnet?
- jne outpr3 ; ne = no
- cmp al,CR ; sending CR?
- jne outpr3 ; ne = no
- push ax
- mov al,LF ; locally show LF which we will send
- call outtty
- pop ax
- outpr3: mov ah,al ; this is where outchr expects it
- call foutchr ; output to the port
- jc outpr4 ; c = failure
- ret
- outpr4: jmp far ptr endcon ; failure, end connection
- outprt endp
-
- fansdsl proc far
- call ansdsl
- ret
- fansdsl endp
-
- foutprt proc far
- call outprt
- ret
- foutprt endp
-
- fprtbout proc far
- call prtbout
- ret
- fprtbout endp
-
- fprtnout proc far
- call prtnout
- ret
- fprtnout endp
-
- ; Product macro worker
- prodwork proc far
- push si
- push di
- push es
- mov ax,ds
- mov es,ax
- mov di,offset decbuf+2 ; macro def buffer starts here
- mov si,offset prodname ; pointer to macro name
- mov cx,vtplen ; length of macro name
- cld
- rep movsb ; copy to rdbuf+2
- mov byte ptr [di],0 ; null terminator
- mov cx,nparam ; number of parameters
- cmp cx,9 ; more than 9?
- jle produc1 ; le = no
- mov cx,9 ; limit to 9
- produc1:jcxz produc3 ; z = none
- xor bx,bx ; parameter subscript
- produc2:push bx
- push cx
- mov al,' ' ; and a space separator
- stosb
- shl bx,1 ; address words
- mov ax,param[bx] ; get parameter to use as definition
- call fdec2di ; convert numerics to ascii string
- pop cx
- pop bx
- inc bx
- loop produc2
- produc3:xor al,al ; safety terminator
- mov [di],al ; don't count in length
- mov ax,di
- sub ax,offset decbuf + 2 ; compute length
- mov vtmaclen,ax ; pass along to vtmacro
- mov vtmacname,offset decbuf+2 ; say this is our macro text ptr
- pop si
- pop di
- pop es
- jmp short vtmacro
- prodwork endp
-
- ;
- ; Reference Macro structure for db number of entries (mac names)
- ; is file table mcctab |-> dw length of macroname
- ; mssset.asm each entry |-> db 'macroname'
- ; where these |-> dw segment:0 of definition string
- ; are stored. (offset part is always 0)
- ; Definition string in db length of <string with null>
- ; buffer macbuf db 'string with trailing null'
- ;
- vtmacro proc far ; common code for macros vtsmac,vtrmac
- push bx ; and Product
- push cx
- push si
- push di
- push es
- mov ax,ds
- mov es,ax
- mov di,offset decbuf+2 ; macro def buffer starts here
- mov si,vtmacname ; pointer to macro name
- mov cx,vtmaclen ; length of macro name<sp/null>text
- mov [di-2],cx ; counted string field
- cld
- rep movsb ; copy to rdbuf
- mov byte ptr [di],0 ; null terminator
- mov si,offset decbuf+2 ; look for name-text separator
- mov cx,vtmaclen
- vtmac1: lodsb
- cmp al,' ' ; space separator?
- je vtmac1a ; e = yes, stop here
- or al,al ; null terminator?
- jz vtmac1a ; e = yes, stop here
- loop vtmac1
- inc si ; to do null length correctly
- vtmac1a:sub si,offset decbuf+2+1 ; compute length of macro name
- mov cx,si
- mov vtmaclen,cx ; save a macro name length
- ; check for existence of macro
- mov bx,offset mcctab ; table of macro names
- mov cl,[bx] ; number of names in table
- xor ch,ch
- jcxz vtmacx ; z = empty table, do nothing
- inc bx ; point to length of first name
- vtmac2: mov ax,[bx] ; length of this name
- cmp ax,vtmaclen ; length same as desired keyword?
- jne vtmac3 ; ne = no, search again
- mov si,bx
- add si,2 ; point at first char of name
- push cx ; save name counter
- push di ; save reg
- mov cx,vtmaclen ; length of name
- mov di,vtmacname ; point at desired macro name
- push es ; save reg
- push ds
- pop es ; make es use data segment
- cld
- repe cmpsb ; match strings
- pop es ; need current si below
- pop cx
- pop di ; recover saved regs
- je vtmac4 ; e = matched
- vtmac3: add bx,ax ; step to next name, add name length
- add bx,4 ; + count and def word ptr
- loop vtmac2 ; try next name
- vtmacx: pop es
- pop di
- pop si ; no macro, return to Connect mode
- pop cx
- pop bx
- stc ; say failure
- ret
-
- vtmac4: cmp taklev,maxtak ; room in Take level?
- jge vtmacx ; ge = no, exit with no action
- inc taklev ; increment take level
- add takadr,size takinfo ; make a new Take entry/macro
- mov bx,takadr ; point to current macro structure
- mov ax,ds ; segment of rdbuf
- mov [bx].takbuf,ax ; segment of definition string struc
- mov cx,word ptr decbuf ; length of count + string
- mov [bx].takcnt,cx ; number of chars in definition
- mov [bx].takargc,0 ; our argument count
- mov [bx].takptr,offset decbuf+2 ; where to read next command char
- mov [bx].taktyp,0ffh ; flag as a macro
- pop es
- pop di
- pop si
- pop cx
- pop bx
- clc ; say success, can exit connect mode
- ret
- vtmacro endp
-
- ; APC macro
- apcmacro proc near
- cmp taklev,maxtak ; room in take level?
- jb apcmac1 ; b = yes
- stc ; fail
- ret
- apcmac1:inc taklev ; increment take level
- add takadr,size takinfo ; make a new Take entry/macro
- mov bx,takadr ; point to current macro structure
- mov ax,apcstring ; segment of buffer
- mov [bx].takbuf,ax ; segment of definition string struc
- mov [bx].takcnt,cx ; number of chars in definition
- mov [bx].takargc,0 ; our argument count
- mov [bx].takptr,0 ; where to read next command char
- mov [bx].taktyp,0ffh ; flag as a macro
- cmp apcenable,2 ; enable all commands?
- je apcmac2 ; e = yes
- mov apctrap,1 ; trap certain commands
- apcmac2:jmp far ptr endcon ; exit Connect mode cleanly
- apcmacro endp
-
- ; Error recovery routine used when outchr reports unable to send character
- ; or when vtmacro requests exiting Connect mode.
- ; Exit Connect mode cleanly, despite layers of intermediate calls.
- endcon proc FAR
- mov kbdflg,'C' ; report 'C' to TERM's caller
- mov sp,oldsp ; recover startup stack pointer
- ; TERM caller's return address is now
- ; on the top of stack. A longjmp.
- jmp quit ; exit Connect mode cleanly
- endcon endp
- code1 ends
-
- code segment
- assume cs:code
- ;;; Action routines (verbs) for keyboard translator KEYBD in msuibm.
- ; These are invoked by a jump instruction. Return carry clear for normal
- ; processing, return carry set for invoking Quit (kbdflg has transfer char).
- uparrw: mov al,'A' ; cursor keys
- jmp short comarr
- dnarrw: mov al,'B'
- jmp short comarr
- rtarr: mov al,'C'
- test vtemu.vtflgop,vswdir ; writing left to right?
- jz comarr ; z = yes
- mov al,'D' ; reverse sense of keys
- jmp short comarr
- lfarr: mov al,'D'
- test vtemu.vtflgop,vswdir ; writing left to right?
- jz comarr ; z = yes
- mov al,'C' ; reverse sense of keys
-
- comarr: test flags.vtflg,ttd463+ttd470 ; DG D463/D470?
- jz comar4 ; z = no
- sub al,'A' ; translate to DG 463/470 form
- cmp tekflg,tek_active+tek_sg ; in special graphics mode?
- jne comar5 ; ne = no
- test dgcross,1 ; DG crosshair active?
- jz comar5 ; z = no
- test dgcross,2 ; DG crosshair active for keypad?
- jz comar5 ; z = no
- mov bx,offset dgcrostab ; use scan code table instead
- xlatb
- call croshair ; send AL to graphics to move cursor
- ret
-
- comar5: mov bx,offset dgcurtab ; VT to DG cursor code table
- xlatb
- push ax ; setup for comar3
- jmp short comar3
-
- comar4: push ax ; save final char
- mov ttyact,0 ; network, group chars for packet
- test vtemu.vtflgop,decanm ; ANSI mode?
- jz comar2 ; z = no
- mov al,CSI ; CSI character
- test vtemu.vtflgop,decckm ; cursor keys in application mode?
- jz comar1 ; z = no, in cursor mode
- mov al,SS3 ; SS3 character
- comar1: call foutprt ; send in 7 or 8 bit form, with echo
- jmp short comar3
-
- comar2: mov al,escape ; do Heath/VT52 mode "ESC char"
- call foutprt
- comar3: pop ax ; recover final char
- mov ttyact,1 ; network, restore tty active flag
- call foutprt
- ret
-
- pf1: mov al,'P' ; keypad function keys PF1-4
- jmp short compf
- pf2: mov al,'Q'
- jmp short compf
- pf3: mov al,'R'
- jmp short compf
- pf4: mov al,'S'
- compf: push ax ; save final char
- mov ttyact,0 ; network, group chars for packet
- test vtemu.vtflgop,decanm ; ansi mode?
- jz short compf1 ; z = no
- mov al,SS3
- call foutprt ; send 7 or 8 bit version
- jmp short compf2
- compf1: mov al,escape ; output ESC
- call foutprt
- compf2: pop ax ; get the saved char
- mov ttyact,1 ; network, restore tty active flag
- call foutprt
- ret
-
- ignore_key: ; key is to be ignored
- ret
-
- kp0: mov al,'p' ; keypad numeric keys
- jmp short comkp
- kp1: mov al,'q'
- jmp short comkp
- kp2: mov al,'r'
- jmp short comkp
- kp3: mov al,'s'
- jmp short comkp
- kp4: mov al,'t'
- jmp short comkp
- kp5: mov al,'u'
- jmp short comkp
- kp6: mov al,'v'
- jmp short comkp
- kp7: mov al,'w'
- jmp short comkp
- kp8: mov al,'x'
- jmp short comkp
- kp9: mov al,'y'
- jmp short comkp
- kpminus:mov al,'m'
- jmp short comkp
- kpcoma: mov al,'l'
- jmp short comkp
- kpenter:mov al,'M'
- jmp short comkp
- kpdot: mov al,'n'
- comkp: test vtemu.vtflgop,deckpam ; keypad application mode active?
- jnz comkp1 ; nz = yes, use escape sequences
- sub al,40h ; deduct offset to numeric symbols
- push ax ; save final char
- jmp short comkp3 ; and send that single char
- comkp1: push ax
- mov ttyact,0 ; network, group chars for packet
- test vtemu.vtflgop,decanm ; ANSI mode?
- jz comkp2 ; z = no
- mov al,SS3 ; SS3 character
- call foutprt ; send 7 or 8 bit version
- jmp short comkp3
- comkp2: mov al,escape ; output "ESC ?"
- call foutprt
- mov al,'?'
- call foutprt
- comkp3: pop ax ; recover final char
- mov ttyact,1 ; network, restore tty active flag
- call foutprt ; send it
- ret
-
- klogon proc near ; resume logging (if any)
- test flags.capflg,logses ; session logging enabled?
- jz klogn ; z = no, forget it
- push bx
- mov bx,argadr
- or [bx].flgs,capt ; turn on capture flag
- pop bx
- or yflags,capt ; set local msy flag as well
- klogn: clc
- ret
- klogon endp
-
- klogof proc near ; suspend logging (if any)
- push bx
- mov bx,argadr
- and [bx].flgs,not capt ; stop capturing
- pop bx
- and yflags,not capt ; reset local msy flag as well
- clc
- ret
- klogof endp
-
- snull proc near ; send a null byte
- xor al,al ; the null
- call fprtbout ; send without logging and local echo
- ret
- snull endp
-
- khold: xor holdscr,1 ; toggle Hold screen byte for msx
- call kbhold ; tell DEC LK250 the hold kbd state
- clc ; kbhold is in file msuibm.asm
- ret
-
- ; Data General "Fn" function keys
- dgkf1: mov al,113 ; F1 sends RS q
- jmp short dgkeyccom
- dgkf2: mov al,114 ; F2 sends RS r
- jmp short dgkeyccom
- dgkf3: mov al,115 ; F3 sends RS s
- jmp short dgkeyccom
- dgkf4: mov al,116 ; F4 sends RS t
- jmp short dgkeyccom
- dgkf5: mov al,117 ; F5 sends RS u
- jmp short dgkeyccom
- dgkf6: mov al,118 ; F6 sends RS v
- jmp short dgkeyccom
- dgkf7: mov al,119 ; F7 sends RS w
- jmp short dgkeyccom
- dgkf8: mov al,120 ; F8 sends RS x
- jmp short dgkeyccom
- dgkf9: mov al,121 ; F9 sends RS y
- jmp short dgkeyccom
- dgkf10: mov al,122 ; F10 sends RS z
- jmp short dgkeyccom
- dgkf11: mov al,123 ; F11 sends RS {
- jmp short dgkeyccom
- dgkf12: mov al,124 ; F12 sends RS |
- jmp short dgkeyccom
- dgkf13: mov al,125 ; F13 sends RS }
- jmp short dgkeyccom
- dgkf14: mov al,126 ; F14 sends RS ~
- jmp short dgkeyccom
- dgkf15: mov al,112 ; F15 sends RS p
- jmp short dgkeyccom
-
- ; Data General "C" keys C1..C4
- dgkc1: mov al,92 ; C1 sends RS \
- jmp short dgkeyccom
- dgkc2: mov al,93 ; C2 sends RS ]
- jmp short dgkeyccom
- dgkc3: mov al,95 ; C3 sends RS ^
- jmp short dgkeyccom
- dgkc4: mov al,96 ; C4 sends RS _
- dgkeyccom: ; common code
- push ax
- mov al,DGescape ; send DG escape (RS)
- call fprtbout ; with no echo
- pop ax
- call fprtbout ; send the second byte
- ret
-
- ; Keyboard "Compose" key to compose characters by the three stroke method
- kbdcompose proc near
- mov grab,1 ; say grabbing normal output
- call togmod
- call togmod ; update mode line
- ret
- kbdcompose endp
-
- ; DG POINT (aka CMD CURSOR-TYPE)
- dgpoint proc near
- cmp tekflg,tek_active+tek_sg ; special graphics mode?
- jne dgpoint1 ; ne = no, ignore cmd
- call dgcrossrpt ; send crosshair report
- dgpoint1:ret
- dgpoint endp
-
- ; DG N/C (normal, compressed font) key
- dgnckey proc near
- test flags.vtflg,ttd470+ttd463 ; DG terminal?
- jz dgnckey1 ; z = no, ignore
- call dgnctoggle ; toggle normal/compressed mode
- dgnckey1:clc
- ret
- dgnckey endp
-
- ; Compose char lookup and reemitter.
- fgrabber proc far
- push bx
- mov bx,grab ; count chars grabbed (want two)
- dec bx ; first char becomes bx=0
- mov grabbox[bx],al ; stuff char in short buffer
- cmp bx,1 ; got both chars?
- pop bx
- jae fgrab2 ; ae = yes, go produce output
- inc grab ; keep grabbing
- ret ; return for the second
- ; process the byte pair
- fgrab2: mov grab,0 ; say done grabbing output
- push dx ; compose new single char result
- push di
- push es
- mov di,seg data1
- mov es,di
- mov di,offset grl1lat ; use Latin1 ptr
- test flags.vtflg,ttd463+ttd470 ; DG D463/D470?
- jz fgrab3 ; z = no
- cmp dgkbl,16 ; Latin1?
- je fgrab3 ; e = yes
- mov di,offset grl1dgi ; get DG Internat ptr to structure
- cmp dgkbl,20 ; DG keyboard language, DG Internat?
- jne fgrab15 ; ne = no
- fgrab3: mov ax,word ptr grabbox ; get pair of chars
- call toupper ; convert AX to upper case
- call match
- jnc fgrab11 ; nc = found
- xchg ah,al
- call match
- jnc fgrab11 ; nc = match
-
- fgrab5: mov di,offset grl2lat ; use Latin1 ptr
- test flags.vtflg,ttd463+ttd470 ; DG D463/D470?
- jz fgrab6 ; z = no
- cmp dgkbl,16 ; Latin1?
- je fgrab6 ; e = yes
- mov di,offset grl2dgi ; get DG Internat ptr to structure
- cmp dgkbl,20 ; DG keyboard language, DG Internat?
- jne fgrab15 ; ne = no
- fgrab6: mov ax,word ptr grabbox
- mov dx,ax
- call toupper ; convert AX to upper case
- call match
- jnc fgrab7 ; nc = found
- xchg ah,al ; try reversed order
- xchg dh,dl
- call match
- jc fgrab8 ; c = not found
- fgrab7: cmp dl,'a' ; lower case char?
- jb fgrab11 ; b = no, upper case
- or al,20h ; move to lower case output codes
- jmp short fgrab11
-
- fgrab8: mov di,offset grl3lat ; use Latin1 ptr
- test flags.vtflg,ttd463+ttd470 ; DG D463/D470?
- jz fgrab9 ; z = no
- cmp dgkbl,16 ; Latin1?
- je fgrab9 ; e = yes
- mov di,offset grl3dgi ; get DG Internat ptr to structure
- cmp dgkbl,20 ; DG keyboard language, DG Internat?
- jne fgrab15 ; ne = no
- fgrab9: mov ax,word ptr grabbox
- xchg ah,al
- call match ; look for matching combination
- jc fgrab16 ; c = failed
- fgrab11:call foutprt ; send it to the host
- fgrab15:call togmod
- call togmod ; update mode line
- pop es
- pop di
- pop dx
- ret
-
- fgrab16:call fvtbell ; mismatch, beep, cancel
- jmp short fgrab15 ; finish up
- fgrabber endp
-
- ; worker for above
- match proc near
- push bx
- push si
- push di
- mov cl,es:[di] ; get count of pairs
- xor ch,ch
- inc di
- mov si,di ; start of char lists
- jcxz match2 ; nothing to look at
- mov si,di ; remember where pairs start
- mov bx,di
- add bx,cx
- add bx,cx ; output singles start here
- cld
- push cx ; save counter
- repne scasw ; look for a match
- pop cx
- jne match2 ; ne = no match
- sub di,2 ; backup to match
- sub di,si ; get item count
- shr di,1 ; count bytes
- mov al,es:[bx+di] ; get new output char
- pop di
- pop si
- pop bx
- clc ; say success
- ret
- match2: pop di
- pop si
- pop bx
- stc ; say no match
- ret
- match endp
-
- toupper proc near
- cmp ah,'a' ; less that lower A?
- jb toupp1 ; b = yes, leave untouched
- cmp ah,'z' ; more than lower Z?
- ja toupp1 ; a = yes
- and ah,not 20H ; convert to uppercase
- toupp1: cmp al,'a' ; less that lower A?
- jb toupp2 ; b = yes, leave untouched
- cmp al,'z' ; more than lower Z?
- ja toupp2 ; a = yes
- and al,not 20H ; convert to uppercase
- toupp2: ret
- toupper endp
-
- ; DEC LK201 keyboard keys and "User Definable Keys" in VT3xx mode
- decfind:mov al,1 ; Find
- jmp udkout
- decinsert:mov al,2 ; Insert
- jmp udkout
- decremove:mov al,3 ; Remove
- jmp udkout
- decselect:mov al,4 ; Select
- jmp udkout
- decprev:mov al,5 ; Previous screen
- jmp udkout
- decnext:mov al,6 ; Next screen
- jmp udkout
- decf6: mov al,17 ; key ident for DEC F6
- jmp udkout ; process it
- decf7: mov al,18 ; key ident for DEC F7
- jmp udkout ; process it
- decf8: mov al,19 ; key ident for DEC F8
- jmp udkout ; process it
- decf9: mov al,20 ; key ident for DEC F9
- jmp udkout ; process it
- decf10: mov al,21 ; key ident for DEC F10
- jmp udkout ; process it
- decf11: mov al,23 ; key ident for DEC F11
- jmp udkout ; process it
- decf12: mov al,24 ; key ident for DEC F12
- jmp udkout ; process it
- decf13: mov al,25 ; key ident for DEC F13
- jmp udkout ; process it
- decf14: mov al,26 ; key ident for DEC F14
- jmp udkout ; process it
- dechelp:mov al,28 ; key ident for DEC HELP
- jmp udkout ; process it
- decdo: mov al,29 ; key ident for DEC DO
- jmp udkout ; process it
- decf17: mov al,31 ; key ident for DEC F17
- jmp udkout ; process it
- decf18: mov al,32 ; key ident for DEC F18
- jmp udkout ; process it
- decf19: mov al,33 ; key ident for DEC F19
- jmp udkout ; process it
- decf20: mov al,34 ; key ident for DEC F20
- jmp udkout ; process it
-
- ; common worker to output contents of User Definable Key definition strings
- ; Enter with al = key ident (17 - 34)
- udkout proc near
- push ax
- push bx
- push cx
- push es
- test flags.vtflg,ttvt320+ttvt220 ; VT320/VT220?
- jnz udkout3 ; nz = yes, else use VT100/VT52 default
- test flags.vtflg,tttek ; Tek?
- jnz udkout3 ; nz = yes, try this
- cmp al,23 ; F11 sends ESC
- jne udkou1a ; ne = not F11
- mov al,escape
- call foutprt
- jmp udkoutx
- udkou1a:cmp al,24 ; F12 sends BS
- jne udkou1b ; ne = not F12
- mov al,BS
- call foutprt
- jmp udkoutx
- udkou1b:cmp al,25 ; F13 sends LF
- jne udkou1c ; ne = not F13, ignore
- mov al,LF
- call foutprt
- udkou1c:jmp udkoutx
-
- udkout3:mov bl,al ; VT3XX key ident, UDK style (17-34)
- cmp al,6 ; is this the CSI 1-6 set?
- jbe udkout4 ; be = yes, do separately
- sub bl,17 ; minus starting offset of 17
- xor bh,bh
- cmp bl,17 ; out of range?
- ja udkoutx ; a = yes, ignore
- shl bx,1 ; index words
- mov bx,udkseg[bx] ; segment of definition
- or bx,bx ; anything there?
- jz udkout4 ; z = no, use DEC defaults below
- mov es,bx ; definition segment
- xor bx,bx ; and offset
- mov cl,es:[bx] ; get string length byte
- xor ch,ch ; use cx as a counter
- jcxz udkout4 ; z = empty, use defaults
- udkou3a:inc bx ; es:bx is now the string text
- mov al,es:[bx] ; get a char
- push bx
- push cx
- push es
- call foutprt ; output
- pop es
- pop cx
- pop bx
- loop udkou3a
- jmp short udkoutx ; done
-
- udkout4:push ax ; VT320, use default definitions
- mov al,CSI ; char to send
- call foutprt ; send lead-in char in 7/8-bit form
- pop ax
- call fprtnout ; key ident (17-34) as ascii digits
- mov al,7eh ; tilde terminator
- call foutprt
- udkoutx:pop es
- pop cx
- pop bx
- pop ax
- clc
- ret
- udkout endp
-
- ; Change Telnet sessions
- nextses proc near
- cmp flags.comflg,'t' ; doing Telnet?
- je nextses1 ; e = yes
- clc ; do not exit Connect mode
- ret
- nextses1:mov bx,sescur ; current session ident
- mov cx,6 ; sessions to consider
- nextses3:inc bx
- cmp bx,6 ; over the top yet
- jb nextses4 ; b = no
- xor bx,bx ; wrap
- nextses4:cmp seslist[bx],0 ; is this session active?
- jge nextses5 ; ge = yes
- loop nextses3
- clc
- ret ; do nothing
-
- nextses5:push bx
- mov bx,sescur ; old session
- call termswapout ; save current terminal items
- pop bx
- mov sescur,bx ; next session, from above
- call tcpstart ; start session, ident in bl
- mov bx,sescur ; new session
- call termswapin ; get data structures
- mov kbdflg,' ' ; return Connect mode
- stc ; but exit Connect mode now
- ret
- nextses endp
-
- vtsesmac proc far ; SESSION macro
- mov vtmacname,offset vtsesname
- mov al,bl ; session number
- add al,'1' ; to ascii, from 1
- mov vtsesnum,al ; to name
- mov vtmaclen,vtseslen
- call dword ptr vtmacroptr ; FAR pointer
- ret
- vtsesmac endp
-
- ; Call from mszibm DG components to put system into DG special graphics mode,
- ; and thus to cause incoming material to be still sent to the text emulator.
- ; This also unshifts the screen (as seen on the status line) before starting
- ; graphics so the column 81 stuff comes out right.
- dgsettek proc far
- cmp tekflg,tek_active+tek_sg ; inited already?
- je dgsettek3 ; e = yes
- push bx
- push cx
- mov cl,byte ptr low_rgt+1 ; examine whole screen
- inc cl ; lines in emulation part
- xor ch,ch
- mov bx,cx ; for status line
- xor al,al
- xchg al,linescroll[bx] ; status line scroll value
- or al,al
- jz dgsettek2 ; z = no shift in effect
- xor bx,bx ; start of screen
- dgsettek1:sub linescroll[bx],al ; unscroll by status line amount
- inc bx ; next line
- loop dgsettek1 ; do all emulation lines
- dgsettek2:pop cx
- pop bx
- or tekflg,tek_sg ; set special graphics mode
- call TEKINI ; go to Tektronix Emulator
- dgsettek3:ret
- dgsettek endp
-
- code ends
-
- code1 segment
- assume cs:code1
-
- ; Set (define) the DEC "User Definable Keys". Inserts text definitions for
- ; keyboard verbs \KdecF6 ...\KdecF14, \KdecHELP, \KdecDO, \KdecF17...\KdecF20.
- ; Enter with the DCS definition string as key-number/hex-chars. UDK key number
- ; is 17 for \KdecF6, et seq, the definition are pairs of hex digits converted
- ; here to a single byte per pair. The DCS definition string is pointed at by
- ; DS:SI, and the byte count is in CX.
- ; Example: 17/54657374204636 means key \KdecF6 sends string "Test F6"
- setudk proc near
- push ax
- push bx
- push cx
- push si
- push di
- push es
- cld
- lodsb ; get key ident first byte
- sub al,'0' ; ascii to binary
- mul ten ; times 10
- xchg ah,al ; to ah
- lodsb ; get key ident second byte
- sub al,'0' ; ascii to binary
- add al,ah ; plus high order part
- xor ah,ah
- mov bx,ax ; key ident, 17 - 34
- lodsb ; skip slash separator
- sub cx,3 ; three less bytes in the string
- jge setudk0 ; ge = had three or more bytes
- jmp setudkx ; else error
- setudk0:sub bx,17 ; remove key ident bias of 17
- cmp bx,17 ; out of range?
- ja setudkx ; a = yes, ignore
- shl bx,1 ; index words
- cmp udkseg[bx],0 ; has a segment been allocated for it?
- je setudk1 ; e = no
- mov ax,udkseg[bx] ; get segment to es
- mov es,ax
- mov ah,freemem ; deallocate old memory block, es:0
- int dos
- mov udkseg[bx],0 ; clear table entry too
- setudk1:and cl,not 1 ; force an even number of inputs
- jcxz setudkx ; z = no definition, clear entry
- push bx ; save index BX
- mov bx,cx ; get string length
- shr bx,1 ; two hex digits per final byte
- add bx,15+1 ; round up plus length byte
- shr bx,1 ; convert to paragraphs
- shr bx,1
- shr bx,1
- shr bx,1
- mov di,bx ; remember request
- mov ah,alloc ; allocate BX paragraphs
- int dos
- jc setudkx ; c = failure
- cmp di,bx ; requested vs allocated
- pop bx ; recover bx
- je setudk2 ; e = enough
- mov ah,freemem ; return the memory, es is ptr
- int dos
- jmp short setudkx ; exit failure
-
- setudk2:mov es,ax ; segment of allocated memory
- mov udkseg[bx],ax ; segment:0 of definition string
- xor di,di
- cld
- mov al,cl ; length of string
- shr al,1 ; two hex bytes per stored byte
- xor ch,ch
- stosb ; store length byte
- jcxz setudkx ; z = empty string
- setukd3:lodsb ; get first hex digit
- dec cx ; adjust count remaining
- or al,20h ; to lower case
- cmp al,'9' ; digit?
- jbe setudk4 ; be = yes
- sub al,'a'-'9'-1 ; hex letter to column three
- setudk4:sub al,'0' ; ascii to binary
- shl al,1 ; times 16
- shl al,1
- shl al,1
- shl al,1
- mov ah,al ; save in ah
- lodsb ; get second hex digit
- or al,20h ; to lower case
- cmp al,'9' ; digit?
- jbe setudk5 ; be = yes
- sub al,'a'-'9'-1 ; hex letter to column three
- setudk5:sub al,'0' ; ascii to binary
- add al,ah ; join both parts
- stosb ; store final byte
- loop setukd3
- setudkx:pop es
- pop di
- pop si
- pop cx
- pop bx
- pop ax
- clc
- ret
- setudk endp
-
- ; Clear all User Definable Keys, deallocate memory for their definitions
- udkclear proc near
- push ax
- push bx
- push cx
- push es
- mov cx,17 ; 17 entries
- xor bx,bx
- udkcle1:mov ax,udkseg[bx] ; segment of definition
- or ax,ax ; segment defined?
- jz udkcle2 ; z = no, try next key
- mov es,ax
- mov udkseg[bx],0 ; clear the entry
- mov ah,freemem ; release the memory
- int dos
- udkcle2:add bx,2 ; word index
- loop udkcle1 ; do all
- pop es
- pop cx
- pop bx
- pop ax
- clc
- ret
- udkclear endp
-
- fsetpos proc far
- call setpos
- ret
- fsetpos endp
-
- frepaint proc far
- call repaint
- ret
- frepaint endp
- code1 ends
-
- code segment
- assume cs:code
- ; these commands invoke Quit
- cdos: mov al,'P' ; Push to DOS
- jmp short cmdcom
- cstatus:mov al,'S' ; Status
- jmp short cmdcom
- cquit: mov al,'C' ; Exit Connect mode
- jmp short cmdcom
- cquery: mov al,'?' ; Help
- jmp short cmdcom
- chang: mov al,'H' ; Hangup, drop DTR & RTS
- jmp short cmdcom
- cmdcom: mov kbdflg,al ; pass char to msster.asm via kbdflg
- stc ; signal that Quit is needed
- ret
- ; general character out for emulator
- chrout proc near
- cmp flags.vtflg,0 ; emulating?
- je chrou5 ; e = no
- call fanskbi ; say we had keyboard input
- cmp al,cr ; CR?
- jne chrou5 ; ne = no, just output it and return
- test vtemu.vtflgop,anslnm ; ANSI new-line mode set?
- jz chrou5 ; z = no, just send the cr
- cmp dupflg,0 ; full duplex?
- je chrou4 ; e = yes
- cmp al,trans.seol ; End of Line char?
- jne chrou5 ; ne = no
- chrou4: mov ah,trans.seol ; save eol char
- push ax ; save on stack
- mov trans.seol,lf ; make LF the eol char
- call foutprt ; output a carriage-return
- mov al,lf ; followed by a line feed
- call foutprt ; send the LF
- pop ax
- mov trans.seol,ah ; restore eol char
- ret
- chrou5: call foutprt
- ret
- chrout endp
-
- ; Screen dump entry from keyboad xlat
- dmpscn proc near ; dump screen to file
- cmp flags.vtflg,tttek ; doing Tektronix emulation?
- je dmpscn2 ; e = yes, use Tek emulator
- cmp tekflg,tek_active+tek_dec ; emulation a Tektronix?
- jne dmpscn1 ; ne = no
- dmpscn2:call tekdmp ; near-call Tek screen dump utility
- clc
- ret
- dmpscn1:call dumpscr ; do buffer to file
- clc ; do not exit Connect mode
- ret
- dmpscn endp
-
- ; Save the screen to a buffer and then append buffer to a disk file. [jrd]
- ; Default filename is Kermit.scn; actual file can be a device too. Filename
- ; is determined by mssset and is passed as pointer dmpname.
- ; Dumpscr reads the screen image saved in vscreen.
-
- dumpscr proc near
- push ax
- push bx
- push cx
- push dx
- mov dmphand,-1 ; preset illegal handle
- mov dx,offset dmpname ; name of disk file, from mssset
- mov ax,dx ; where isfile wants name ptr
- call fisfile ; what kind of file is this?
- jc dmp5 ; c = no such file, create it
- test byte ptr filtst.dta+21,1fh ; file attributes, ok to write?
- jnz dmp0 ; nz = no.
- mov al,1 ; writing
- mov ah,open2 ; open existing file
- int dos
- jc dmp0 ; c = failure
- mov dmphand,ax ; save file handle
- mov bx,ax ; need handle here
- mov cx,0ffffh ; setup file pointer
- mov dx,-1 ; and offset
- mov al,2 ; move to eof minus one byte
- mov ah,lseek ; seek the end
- int dos
- jmp dmp1
-
- dmp5: test filtst.fstat,80h ; access problem?
- jnz dmp0 ; nz = yes
- mov ah,creat2 ; file did not exist
- mov cx,20h ; attributes, archive bit
- int dos
- mov dmphand,ax ; save file handle
- jnc dmp1 ; nc = ok
-
- dmp0: mov ah,3 ; get cursor position
- xor bh,bh ; page 0
- int screen
- push dx ; save it
- mov dh,byte ptr low_rgt+1 ; go to status line
- inc dh
- xor dl,dl ; left most column
- mov ah,2 ; set cursor
- xor bh,bh ; page 0
- int screen
- mov dx,offset dmperr ; say no can do
- mov ah,prstr
- int dos
- pop dx ; get original cursor position
- mov ah,2 ; set cursor
- xor bh,bh ; page 0
- int screen
- pop dx
- pop cx
- pop bx
- pop ax
- clc
- ret
-
- dmp1: mov ah,ioctl ; is destination ready for output?
- mov al,7 ; test output status
- mov bx,dmphand ; handle
- int dos
- jc dmp0 ; c = error
- cmp al,0ffh ; ready?
- jne dmp0 ; ne = not ready
- push di ; read screen buffer, write lines
- push si
- push es
- mov cl,byte ptr low_rgt+1 ; number of lines - 2
- add cl,2 ; number of line on screen
- xor ch,ch
- les si,vs_ptr ; seg and offset of vscreen
- sub si,vswidth*2 ; prep for inc below
- dmp2: add si,vswidth*2 ; virtual screen width in bytes
- push si
- push cx ; save outer loop counter
- push di
- mov di,offset decbuf ; data segment memory
- mov cl,byte ptr low_rgt ; number of columns on screen -1
- inc cl
- xor ch,ch
- dmp3: mov ax,word ptr es:[si] ; read char + attribute
- or al,al ; is it a null?
- jnz dmp3c ; nz = no
- mov al,' ' ; replace null with space
- dmp3c: mov byte ptr [di],al ; store just char, don't use es:
- inc si ; update pointers
- inc si
- inc di
- loop dmp3 ; do for each column
- mov cl,byte ptr low_rgt ; number of columns on screen - 1
- inc cl
- xor ch,ch
- push es
- mov ax,ds
- mov es,ax ; set es to data segment for es:di
- mov di,offset decbuf ; start of line
- add di,cx ; plus length of line
- dec di ; minus 1 equals end of line
- mov al,' ' ; thing to scan over
- std ; set scan backward
- repe scasb ; scan until non-space
- cld ; set direction forward
- pop es
- je dmp3a ; e = all spaces
- inc cx
- inc di
- dmp3a: mov word ptr [di+1],0A0Dh ; append cr/lf
- add cx,2 ; line count + cr/lf
- mov dx,offset decbuf ; array to be written
- mov bx,dmphand ; need file handle
- mov ah,write2 ; write the line
- int dos
- pop di
- pop cx ; get line counter again
- pop si ; screen offset
- jc dmp3b ; c = error
- loop dmp2 ; do next line
- dmp3b: mov dx,offset dumpsep ; put in formfeed/cr/lf
- mov bx,dmphand ; need file handle
- mov cx,3 ; three bytes overall
- mov ah,write2 ; write them
- mov bx,dmphand ; file handle
- int dos
- mov bx,dmphand ; need file handle
- mov ah,close2 ; close the file now
- int dos
- pop es
- pop si
- pop di
- pop dx
- pop cx
- pop bx
- pop ax
- clc
- ret
- dumpscr endp
-
- togmod proc FAR
- call trnmod ; FAR callable trnmod
- ret
- togmod endp
-
- ; Toggle Mode Line
- trnmod proc near
- cmp inemulator,0 ; in terminal emulator?
- je trnm1 ; e = no, no mode line
- cmp flags.modflg,1 ; mode line enabled and owned by us?
- jne trnm1 ; ne = no, don't touch it
- cmp flags.vtflg,tttek ; Tek mode?
- je trnm1 ; e = yes
- test tekflg,tek_dec ; in Tek submode?
- jnz trnm1 ; nz = yes, no mode line changes
- test yflags,modoff ; mode line already off?
- jnz trnm2 ; nz = yes, go turn on
- or yflags,modoff ; say modeline is toggled off
- cmp flags.vtflg,0 ; emulating none?
- jne trnm0 ; ne = no
- push dx
- call fgetpcur ; get physical cursor
- mov cursor,dx
- pop dx
- trnm0: call clrmod ; clear mode line
- trnm1: clc ; clear c bit so don't exit Connect
- ret
- trnm2: cmp flags.vtflg,0 ; emulating a terminal?
- jne trnm3 ; ne = yes
- push dx ; scroll screen to save bottom line
- call fgetpcur ; get physical cursor
- mov cursor,dx
- mov ah,prstr ; for terminal type none
- mov dx,offset crlf
- int dos
- pop dx
- trnm3: call modlin ; turn on modeline
- and yflags,not modoff ; say modeline is not toggled off
- clc
- ret
- trnmod endp
-
- modlin proc near
- push si
- push di
- push es
- mov ax,ds
- mov es,ax
- mov si,offset modmaster ; master template
- mov di,offset modbuf ; working copy
- cld
- modl20: lodsb
- stosb
- cmp al,'$' ; at end?
- jne modl20 ; ne = no
- mov al,trans.escchr ; Connect mode escape character
- mov modbuf.m_echr,' ' ; first char is initial space
- mov modbuf.m_hlp,' ' ; goes here too
- cmp al,32 ; printable?
- jnb modl1 ; yes, keep going
- add al,40h ; made printable
- mov modbuf.m_echr,5eh ; caret, note control char
- mov modbuf.m_hlp,5eh
- modl1: mov modbuf.m_echr+1,al ; fill in character
- mov modbuf.m_hlp+1,al
- mov bx,argadr ; get argument block
- mov al,[bx].baudb ; get baud bits
- mov si,offset unkbaud ; assume unknown baud
- mov cx,size m_baud ; length of baud space
- cmp al,baudnsiz ; beyond end of table?
- jnb modl2 ; nb = yes, use default
- mul cl
- xor ah,ah
- add ax,offset baudn
- mov si,ax
- modl2: mov di,offset modbuf.m_baud
- cld
- rep movsb ; copy in baud rate
- mov bx,portval
- mov al,[bx].parflg ; get parity code
- shl al,1 ; each is 4 bytes long
- shl al,1
- xor ah,ah
- add ax,offset parnams ; names of parity settings
- mov si,ax
- mov cx,4 ; each is 4 long
- mov di,offset modbuf.m_par
- rep movsb
- mov si,offset remmsg ; assume remote echoing
- test yflags,lclecho ; local echo on?
- jz modl3 ; z = no
- mov si,offset lclmsg ; say echo is local
- modl3: mov cx,3 ; size of on/off
- mov di,offset modbuf.m_echo
- rep movsb
- mov al,portno ; communications port
- cmp al,' ' ; binary (non-printable)?
- jae modl4 ; ae = no, ascii
- add al,'0' ; convert to ascii
- modl4: mov modbuf.m_prt,al ; fill in port number
- mov al,portno
- cmp repflg,0 ; REPLAY?
- je modl5 ; e = no
- mov si,offset repmsg ; say "REPLAY"
- mov cx,repmsgl ; its length
- mov di,offset modbuf.m_prt
- mov al,' ' ; start with a space
- stosb
- mov dx,12 ; space to be filled
- sub dx,cx ; amount we will use here
- rep movsb ; copy string
- mov cx,dx
- rep stosb ; flesh out with spaces
- jmp short modl10
-
- modl5: cmp al,'4' ; in networks material?
- jbe modl10 ; be = no
- cmp flags.comflg,'t' ; doing TCP/IP Telnet?
- jne modl5d ; ne = no
- mov si,offset tcphost ; name of host
- mov di,offset modbuf.m_prt - 6 ; overwrite "port:"
- mov ax,sescur ; ident of session
- add al,'1' ; ascii, show as 1:nodename
- mov ah,':'
- stosw ; store that much
- mov cx,17 ; bytes max
- modl5a: lodsb
- or al,al ; at null terminator?
- jz modl5b ; z = yes
- stosb
- loop modl5a
- modl5b: mov al,' ' ; fill out with spaces
- rep stosb ; noop if cx == 0
- jmp short modl5d ; done with tcp/ip
-
- modl5d: mov bx,offset comptab ; table of comms ports
- mov cl,[bx] ; number of entries
- xor ch,ch
- inc bx
- modl6: mov dx,[bx] ; length of this entry
- mov si,bx
- add si,2 ; points to entry text string
- add si,dx ; point to qualifier
- cmp [si],al ; our port?
- je modl7 ; e = yes
- add bx,[bx] ; add text length
- add bx,4 ; plus count and qualifier
- loop modl6 ; next entry
- jmp short modl10 ; no match, curious
- modl7: mov si,bx ; point at entry
- add si,2 ; point at string
- mov cx,[bx] ; length of string
- mov di,offset modbuf.m_prt
- mov al,' ' ; start with a space
- stosb
- mov dx,12 ; space to be filled
- sub dx,cx ; amount we will use here
- rep movsb ; copy string
- mov cx,dx
- rep stosb ; flesh out with spaces
- modl10: mov cx,8 ; blank out terminal id field
- mov si,offset mtty ; assume no terminal emulation
- mov di,offset modbuf.m_term ; destination
- rep movsb ; copy it in
- mov word ptr modbuf.m_prn,' '; assume not printing the screen
- mov modbuf.m_prn+2,' '
- test anspflg,prtscr+2 ; print the screen? (msz uses 1 & 2)
- jz modl10a ; z = no
- mov word ptr modbuf.m_prn,'RP' ; yes. display PRN at end of line
- mov modbuf.m_prn+2,'N'
- modl10a:mov modbuf.m_comp,' ' ; flag for not-compose
- cmp grab,0 ; doing Compose grabbing?
- je modl11 ; e = no
- mov modbuf.m_comp,'C' ; flag for compose
- modl11: cmp inemulator,0 ; in terminal emulator now?
- jne modl11a ; ne = yes
- pop es ; do nothing
- pop di
- pop si
- ret
- modl11a:push dx
- cmp flags.vtflg,0 ; emulating?
- je modl12 ; e = no
- and yflags,not modoff ; update local flags (mode line on)
- call fansdsl ; get extras from emulator
- modl12: mov dx,offset modbuf ; mode line image ptr for putmod
- call putmod ; display mode line
- mov dx,cursor ; restore active cursor position
- call fsetpos ; set cursor
- pop dx
- pop es
- pop di
- pop si
- ret
- modlin endp
-
- fmodlin proc far
- call modlin
- ret
- fmodlin endp
-
- ;[IU2] Routine to toggle VT100/VT52/Heath-19 modes in VT100 emulator.
- vtans52 proc near
- cmp flags.vtflg,0 ; emulating?
- je vtans52a ; e = no
- call ans52t ; call MSZ toggle-it routine
- cmp flags.vtflg,tttek ; Tek now?
- je vtans52a ; e = yes
- test tekflg,tek_tek+tek_dec ; Tek submode?
- jnz vtans52a ; nz = yes
- call scrini ; check on screen size changes
- vtans52a:clc ; clear c bit so don't exit Connect
- ret
- vtans52 endp
-
- ftrnprs proc far
- call trnprs
- ret
- ftrnprs endp
-
- trnprs proc near
- push ax ; toggle ^ PrtSc screen to printer
- test anspflg,prtscr ; are we currently printing?
- jnz trnpr2 ; nz = yes, its on and going off
- push bx
- mov bx,prnhand ; file handle for system printer
- mov ah,ioctl
- mov al,7 ; get output status of printer
- int dos
- pop bx
- jc trnpr1 ; c = printer not ready
- cmp al,0ffh ; Ready status?
- je trnpr2 ; e = Ready
- trnpr1: call fvtbell ; Not Ready, complain
- jmp trnpr3 ; and ignore request
- trnpr2: xor anspflg,prtscr ; flip the flag
- test yflags,modoff ; mode line off?
- jnz trnpr3 ; nz = yes
- call fmodlin ; else rewrite mode line
- trnpr3: pop ax
- clc ; return carry clear (don't quit)
- ret
- trnprs endp
- code ends
-
- code1 segment
- assume cs:code1
-
- pntdead proc near ; display printer is inoperative msg
- push ax
- test yflags,modoff ; is mode line off?
- jnz pntdea1 ; nz = off, skip msg
- push bx
- mov dx,offset pntmsg ; say printer not ready
- call fputmod ; write on mode line
- pop bx
- pntdea1:pop ax
- stc ; say printer not ready
- ret
- pntdead endp
-
- ;;;;; General screen management routines for IBM PC
-
- ; computes screen location to ax, given row and col in [dh,dl], resp.
-
- scrloc proc near
- push cx
- mov cl,crt_cols
- cmp inemulator,0 ; emulating?
- je scrloc1 ; e = no
- cmp flags.vtflg,0 ; emulating anything?
- je scrloc1 ; e = no
- mov cl,vswidth
- scrloc1:mov al,dh ; get row
- mul cl ; multiply by number of columns
- add al,dl ; plus current column number
- adc ah,0 ; ripple carry
- shl ax,1 ; double for attributes
- pop cx
- ret
- scrloc endp
-
- ; Routine to set cursor type. Pass cursor type in al: 0,4 = No cursor,
- ; 1 = Underline cursor, 2 = Block cursor. All cursors blink due to hardware.
- ; For EGA boards running in non-25 line mode the cursor emulation is turned
- ; off during cursor shape changing and restored afterward. It's another
- ; ega Feature. [jrd]
- ; Sense crt_mode 18h as Tseng Labs UltraPAK mono board in 132 column mode.
- csrtype proc near
- push cx ; save the reg
- mov cx,0F00H ; assume no cursor
- test al,4 ; no cursor?
- jz csrtyp6 ; z = no
- xor al,al ; set type to invisible
- csrtyp6:or al,al ; no cursor?
- jz csrty2 ; z = yes, no cursor
- cmp crt_mode,7 ; B&W card?
- je csrty3 ; e = yes, different sizes
- cmp crt_mode,18h ; Tseng UltraPAK mono board?
- je csrty3 ; e = yes, use mono cursor
- mov cx,0607H ; use CGA underline cursor
- cmp al,2 ; Block?
- jne csrty2 ; ne = no, set it now
- csrty1: xor ch,ch ; make cursor a block
- csrty2: cmp ega_mode,0 ; ega board active?
- je csrty4 ; e = no
- test tv_mode,10h ; DV active?
- jnz csrty4 ; nz = yes, it messes with the cursor
- cmp byte ptr low_rgt+1,23 ; standard screen length?
- je csrty4 ; e = yes, use regular cursor setting
- push es ; EGA. turn off cursor emulation
- mov ax,40h ; 40:87h is ega Info byte
- mov es,ax
- push es:[87h] ; save Info byte around call
- or byte ptr es:[87h],1 ; set emulation off (low bit = 1)
- mov ah,1 ; video function for set cursor type
- int screen
- pop es:[87h] ; restore Info byte
- pop es ; and our work register
- pop cx
- ret
-
- csrty4: push ax
- mov ah,1 ; video function for set cursor type
- int screen ; regular cursor shape setting
- pop ax
- csrty5: pop cx
- ret
-
- csrty3: mov cx,0B0CH ; assume B&W underline cursor
- cmp al,2 ; Block?
- jne csrty2 ; ne = no, set it now
- jmp short csrty1 ; make it a block
- csrtype endp
-
- fcsrtype proc far
- call csrtype
- ret
- fcsrtype endp
-
- ; Get CRT mode - returns mode in variable crt_mode,
- ; updates crt_cols, and low_rgt.
- ; For EGA active it looks in Bios work memory 40:84H for number of rows
- scrmod proc near
- push ax
- push dx
- mov ah,0fh ; get current video state
- int screen
- and al,not 80h ; strip "preserve regen" bit 80h
- mov crt_mode,al ; store CRT mode value
- mov crt_cols,ah ; store # of cols
- mov dl,ah ; # of cols again
- mov dh,crt_lins ; and # of rows (constant from msster)
- cmp tv_mode,0 ; Topview active?
- je scrmod2 ; e = no
- test tv_mode,20h ; Japanese DOS active?
- jnz scrmod2 ; nz = yes, do not do Int 15h
- push cx
- push bx
- mov ah,12h ; TV, Get Object Length
- mov bx,0901h ; object, BL = 01 = chars/line
- int 15h
- pop ax ; chars/line from stack dword
- cmp al,10 ; keep things sane, chars per line
- ja scrmod7 ; a = might be sane
- pop ax ; clean stack
- jmp scrmod2 ; wacko, ignore DV stuff
-
- scrmod7:mov crt_cols,al ; TV windowed screen columns
- pop ax ; clear rest of dword from stack
- mov ah,12h ; send
- mov bx,1 ; handle (0*256) + window (me, 1)
- int 15h
- pop bx ; handle low word
- pop bx ; handle high word to BX for next call
- mov ax,1024h ; TV Get Virtual Screen Info
- int 15h
- scrmod1:cmp cx,128*25*2 ; get sanity for DV big DOS window
- jbe scrmod1a ; be = reasonable size
- shr cx,1 ; reduce size
- jmp short scrmod1 ; and try again
- scrmod1a:mov ax,cx ; CX is virtual screen size, bytes
- mov bl,crt_cols ; divide by columns to get width
- shl bl,1 ; get words (char and attribute)
- div bl ; al = lines, ah = fractions of line
- dec al ; count this from zero like the Bios
- mov crt_lins,al ; visible screen lines -1 (24)
- mov dh,al
- mov dl,crt_cols ; visible screen columns (80)
- pop bx
- pop cx
- jmp short scrmod4
-
- scrmod2:cmp ega_mode,0 ; ega active?
- je scrmod4 ; e = no
- push es ; yes, permit different lengths
- mov ax,40h ; refer to 40:84h for # ega rows
- mov es,ax
- mov ah,es:[84h] ; get number of rows - 1 (typ 24)
- cmp ah,20 ; less than 20 rows?
- jb scrmod3 ; b = yes, ignore this length
- cmp ah,80 ; more than 80 rows?
- ja scrmod3 ; a = yes, ignore this length
- mov dh,ah ; use this length
- mov crt_lins,dh ; update our working constant
- scrmod3:pop es
- scrmod4:dec dl ; max text column, count from zero
- dec dh ; max text row, count from zero
- cmp flags.vtflg,ttgenrc ; no terminal emulation
- je scrmod6 ; e = yes
- cmp tekflg,tek_active+tek_sg ; doing special graphics?
- jne scrmod4a ; ne = no
- mov crt_cols,128 ; VT style special graphics uses this
- scrmod4a:
- cmp crt_cols,80 ; doing wide now?
- ja scrmod5 ; a = yes
- mov dl,80-1 ; assume 80 column width
- test vtemu.vtflgop,deccol ; 132 column mode set?
- jz scrmod6 ; z = no
- scrmod5:mov dl,132-1 ; set to 132 column mode
- scrmod6:mov low_rgt,dx ; save away window address
- pop dx
- pop ax
- ret
- scrmod endp
-
- ; Get screen segment. Returns screen segment in ax, and full address in es:di
- scrseg proc near
- xor di,di ; start at beginning of screen (0,0)
- mov ax,0B800H ; video memory is here on color
- cmp crt_mode,7 ; normal color modes?
- jb scrse1 ; b = yes
- mov ax,0B000H ; assume B&W card
- cmp crt_mode,12 ;
- jb scrse1
- cmp crt_mode,18h ; Tseng UltraPAK mono in 132 col?
- je scrse1 ; e = yes, use seg B000H
- cmp crt_mode,56h ; Paradise EGA Mono in 132x43 mode?
- je scrse1 ; e = yes, use seg B000H
- cmp crt_mode,57h ; Paradise EGA Mono in 132x25 mode?
- je scrse1 ; e = yes, use seg B000H
- mov ax,0B800H ; video memory is here on color
- cmp crt_mode,18 ; end of ordinary 640x480 graphics
- ja scrse1 ; a = no, assume CGA segment
- mov ax,0A000H ; graphics
- scrse1: mov es,ax ; tell Topview our hardware address needs
- mov tv_segs,es ; save our hardware screen address
- mov tv_sego,di ; segment and offset form
- or tv_mode,1 ; assume we're running under Topview
- mov ah,tvhere ; query Topview for its presence
- int screen
- mov ax,es ; get its new segment for screen work
- cmp ax,tv_segs ; same as hardware?
- jne scrse2 ; ne = no, we are being mapped
- cmp di,tv_sego ; check this too
- jne scrse2 ; ne = no too. Use TV's work buf as screen
- and tv_mode,not 1 ; else no Topview or no mapping
- scrse2: mov tv_segs,es ; save segment
- mov tv_sego,di ; and offset
- ret
- scrseg endp
-
- ; Synchronize a Topview provided virtual screen buffer with the image
- ; seen by the user. Requires cx = number of words written to screen
- ; (char & attribute bytes) and es:di = ENDING address of screen write.
- ; Changes ax and di. Skip operations for DESQview
- scrsync proc near
- cmp tv_mode,0 ; Topview mode active?
- je scrsyn1 ; e = no, skip Bios call below
- push ax
- push cx
- push di
- sub di,cx ; backup to start byte (cx = words)
- sub di,cx ; after storing words to screen
- mov ah,tvsynch ; tell Topview we have changed screen
- int screen ; so user sees updated screen
- pop di
- pop cx
- pop ax
- scrsyn1:ret
- scrsync endp
-
- ; The following two routines are used to turn off the display while we
- ; are reading or writing the screen in one of the color card modes.
- ; Turn screen off for (known) color card modes only. All regs preserved.
- ; Includes code for old procedure scrwait. 16 June 1987 [jrd]
- scroff proc near
- cmp ega_mode,0 ; Extended Graphics Adapter in use?
- jne scrofx ; ne = yes, no waiting
- cmp tv_mode,0 ; Topview mode?
- jne scrofx ; ne = yes, no waiting
- cmp crt_mode,7 ; B&W card?
- jnb scrofx ; nb = yes - just return
- cmp refresh,0 ; slow refresh?
- jne scrofx ; ne = no wait
- push ax ; save ax and dx
- push dx
- mov dx,crt_status ; CGA: Wait for vertical retrace
- scrof1: in al,dx
- test al,disp_enb ; display enabled?
- jnz scrof1 ; yes, keep waiting
- scrof2: in al,dx
- test al,disp_enb ; now wait for it to go off
- jz scrof2 ; so can have whole cycle
- mov dx,crtmset ; output to CRT mode set port
- mov al,25H ; this shuts down the display
- out dx,al
- pop dx ; restore regs
- pop ax
- scrofx: ret
- scroff endp
-
-
- ; Turn screen on for (known) color card modes only
- ; All registers are preserved.
-
- scron proc near
- cmp ega_mode,0 ; Extended Graphics Adapter in use?
- jne scronx ; ne = yes, no waiting
- cmp tv_mode,0 ; Topview mode?
- jne scronx ; ne = yes, no waiting
- cmp crt_mode,7 ; B&W card?
- jnb scronx ; nb = yes - just return
- cmp refresh,0 ; slow refresh?
- jne scronx ; ne = no wait
- push ax ; save ax, dx, and si
- push dx
- push si
- mov al,crt_mode ; convert crt_mode to a word
- xor ah,ah
- mov si,ax ; get it in a usable register
- mov al,msets[si] ; fetch the modeset byte
- mov dx,crtmset ; this port
- out dx,al ; flash it back on
- pop si
- pop dx
- pop ax
- scronx: ret
- scron endp
-
-
- ; Determine screen roll back buffer parameters depending on current screen
- ; dimensions and available memory. Each rollback screen line has its own
- ; segment (lines start on segment boundaries for rollback). One full screen
- ; must be allocated to hold the current display, deduct this from lmax.
-
- bufadj proc near
- push bx
- push cx
- push dx
- mov bx,rollwidth ; rollback line width
- add bx,7 ; (BDT) round up to paragraph boundary
- mov cl,3 ; (BDT) now convert to
- shr bx,cl ; (BDT) paragraphs / line
- mov ppl,bx ; (BDT) save this in buffer area
- xor dx,dx ; high order dividend, clear it
- cmp emsrbhandle,0 ; using EMS?
- jle bufadj2 ; le = no (-1 means not used)
- mov ax,1024 ; 1024 paragraphs per ems 16KB page
- div bx ; divide by paragraphs per line
- mov lineems,ax ; lines per ems page, remember
- mul inipara ; times number of ems pages
- jmp short bufadj3 ; ax has number of lines
- ; conventional memory
- bufadj2:mov ax,inipara ; (BDT) compute the number of lines
- div bx ; (BDT) in the buffer
-
- bufadj3:mov lmax,ax ; max line capacity of the buffer
- mov linee,ax ; (BDT) save as number of total lines
- or ax,ax ; have any lines?
- jz bufadj1 ; z = yes, no space at all
- xor bh,bh ; (BDT) get lines / screen
- mov bl,byte ptr low_rgt+1 ; (BDT) rows on user/host screen
- inc bx ; (BDT) adjust for counting from 0
- sub lmax,bx ; minus master "current" screen
- jg bufadj1 ; g = have some rollback space
- mov lmax,0 ; say none
- bufadj1:mov lcnt,0 ; (BDT) # of lines filled in buffer
- mov linef,0 ; (BDT) first filled in line
- mov linec,0 ; (BDT) last filled in line
- pop dx
- pop cx
- pop bx
- ret
- bufadj endp
-
- ; Test for DESQview in operation, set tv_mode bit 10h to non-zero if so.
- dvtest proc near
- and tv_mode,not 30h ; assume no DV and no Japanese DOS
- push ds
- mov ax,ds ; preset es:si to start of data seg
- mov es,ax ; as saftey factor after test
- xor si,si
- mov ax,6300h ; get Doublebyte Char Set Lead Table
- int dos ; returns ptr in ds:si
- mov bx,ds ; cannot trust al as return status
- mov es,bx
- pop ds
- mov ax,ds ; current DS
- cmp ax,bx ; same seg?
- je dvtest4 ; e = yes, test failed
- cmp word ptr es:[si],0 ; see if both bytes are also zeros
- je dvtest4 ; z = test failed
- or tv_mode,20h ; say Japanese DOS is active
- ret ; do no Int 15h with Japanese DOS
- dvtest4:xor bx,bx ; for version number
- mov cx,'DE' ; DV signature
- mov dx,'SQ'
- mov ax,2B01h ; DOS set date (with illegal value)
- int dos
- cmp al,0ffh ; DOS should say invalid if no DV
- je dvtest2 ; e = yes, invalid so no DV
- cmp bx,2 ; DV version 2.00?
- jne dvtest1 ; ne = no
- xchg bh,bl ; get major version into bh
- dvtest1:or tv_mode,10h ; say using DV
- dvtest2:ret
- dvtest endp
-
- ; Execute DESQview function call provided in BX.
- dvcall proc near
- push ax
- mov ax,101ah ; switch to DV stack
- int 15h
- mov ax,bx ; function to do
- int 15h
- mov ax,1025h ; switch from DV stack
- int 15h
- pop ax
- ret
- dvcall endp
-
- ; Call this to release the cpu during idle times
- dvpause proc near
- test tv_mode,10h ; in DV?
- jz dvpaus1 ; z = no
- push bx
- mov bx,1000h ; say release control
- call dvcall ; to DV
- pop bx
- dvpaus1:cmp byte ptr dosnum+1,5 ; DOS verson, major high, minor low
- jb dvpaus2 ; b = too old for this operation
- mov ax,1680h ; release current virtual machine
- int 2fh ; time slice (Windows, OS/2, DPMI)
- dvpaus2:ret
- dvpause endp
-
- ; Screen clearing routine
- ; Call: ax = coordinates of first screen location to be cleared.
- ; bx = coordinates of last location to be cleared.
- ; Coord: ah = row [0-24], al = column [0-206]. Preserves all registers.
-
- atsclr proc near
- push ax ; save regs
- push cx
- mov ch,scbattr ; save current screen background attr
- push cx
- push dx
- mov dx,bx ; compute last screen offset from bx
- push ax
- call scrloc ; get screen start address in ax
- mov cx,ax ; save it in cx for a minute
- pop dx ; compute first screen offset in ax
- call scrloc
- sub cx,ax ; compute number of locs to clear
- add cx,2 ; +1 for span, +1 for round up
- sar cx,1 ; make byte count a word count
- jle atscl3 ; le = nothing to clear
- push di ; save regs
- push es ; save es
- cmp inemulator,0 ; in terminal emulator now?
- je atscl1 ; e = no
- cmp flags.vtflg,0 ; emulating anything?
- je atscl1 ; e = no, using DOS
- les di,vs_ptr ; es:di is virtual screen
- jmp short atscl2
- atscl1: push ax ; save displacement
- call scroff ; turn screen off if color card
- call scrseg ; get address of screen into es:di
- pop ax
- atscl2: add di,ax ; location in buffer
- mov ah,scbattr ; use current screen background attr
- mov al,' ' ; use space for fill
- push cx ; save word count for Topview
- cld
- rep stosw ; copy to screen
- pop cx ; recover word count
- cmp inemulator,0 ; in terminal emulator now?
- je atscl2a ; e = no
- cmp flags.vtflg,0 ; emulating anything?
- jne atscl2b ; ne = yes
- atscl2a:call scrsync ; synch Topview
- call scron ; turn screen back on if color card
- atscl2b:pop es
- pop di
- atscl3: pop dx
- pop cx
- mov scbattr,ch ; recover current screen bkg attr
- pop cx
- pop ax ; back to regs at call time
- cmp inemulator,0 ; in terminal emulator now?
- je atscl6 ; e = no
- cmp flags.vtflg,0 ; emulating anything?
- je atscl6 ; e = no, using DOS
- push dx ; do extended attributes
- push ax
- push bx
- push cx
- mov dx,ax ; starting place
- mov al,dh ; row
- mov cl,((vswidth+1)/2)*2 ; row char cells
- mul cl
- add al,dl ; plus starting column
- adc ah,0 ; char cells to starting place
- mov dx,ax ; save here
- mov al,bh ; ending row
- mul cl
- add al,bl ; plus ending column
- adc ah,0
- mov bx,ax
- sub bx,dx ; number of cells -1 to clear
- inc bx
- mov cx,bx ; cx = cells to clear
- xchg bx,dx ; bx = start offset, dx=cells
- push es
- push di
- les di,vsat_ptr ; where attributes are stored
- shr cx,1 ; cells to bytes, rounded down
- inc bx ; round up
- shr bx,1 ; cells to bytes
- jc atscl4 ; c = no odd start, can do whole bytes
- and byte ptr es:[di+bx-1],0fh ; clear initial (high) nibble
- dec dx ; one less cell
- atscl4: add di,bx ; offset plus start byte
- xor al,al
- cld
- rep stosb ; clear those bytes
- test dl,1 ; odd nibble at the end?
- jz atscl5 ; z = no, done
- and byte ptr es:[di],0f0h ; clear last (low) nibble
- atscl5: pop di
- pop es
- pop cx
- pop bx
- pop ax
- mov dl,ah ; first row
- mov dh,bh ; last row
- call touchup ; repaint this part of the screen
- pop dx ; finish cleaning stack
- atscl6: ret
- atsclr endp
-
-
- ; Screen-scrolling routines.
-
- fhomwnd proc far ; "home" to start of the buffer
- mov cl,byte ptr low_rgt+1 ; save this many lines
- inc cl ; full text screen
- xor ch,ch
- call putcirc ; save them
- mov linec,0 ; reset the current pointer
- call getcirc ; now get the new screen
- clc
- ret
- fhomwnd endp
-
- fendwnd proc far ; "end" to end of the buffer
- mov cl,byte ptr low_rgt+1 ; save this many lines
- inc cl ; full text screen
- xor ch,ch
- call putcirc ; save them
- mov ax,lcnt ; reset the current pointer
- mov linec,ax ; save the results
- call getcirc ; now get the new screen
- clc
- ret
- fendwnd endp
-
- fdnwpg proc far ; scroll down 1 page
- mov cl,byte ptr low_rgt+1 ; save this many lines
- inc cl ; full text screen
- xor ch,ch
- call putcirc ; save them
- mov ax,linec ; reset the current pointer
- add ax,cx
- cmp ax,lcnt ; did we go past the end?
- jbe dnwpg1 ; be = no, we're OK
- mov ax,lcnt ; yup, back up
- dnwpg1: mov linec,ax ; save the results
- call getcirc ; now get the new screen
- clc
- ret
- fdnwpg endp
-
- fdnone proc far ; scroll down 1 line
- mov cl,byte ptr low_rgt+1 ; save this many lines
- inc cl ; full text screen
- xor ch,ch
- call putcirc ; save them
- mov ax,linec ; reset the current pointer
- inc ax ; to the next line
- cmp ax,lcnt ; oops, did we go past the end?
- jbe dnone1 ; be = no, we're OK
- mov ax,lcnt ; yup, back up
- dnone1: mov linec,ax ; save the results
- call getcirc ; now get the new screen
- clc
- ret
- fdnone endp
-
- fupwpg proc far ; scroll up 1 page
- mov cl,byte ptr low_rgt+1 ; save this many lines
- inc cl ; full text screen
- xor ch,ch
- call putcirc ; save a full screen
- mov ax,linec ; reset the current pointer
- sub ax,cx ; to the previous page
- jge upwpg1 ; ge = not past end, we're OK
- xor ax,ax ; stop at the beginning of the buffer
- upwpg1: mov linec,ax ; line counter to use
- call getcirc ; get the new screen
- clc
- ret
- fupwpg endp
-
- fupone proc far ; scroll up 1 line
- mov cl,byte ptr low_rgt+1 ; save this many lines
- inc cl ; full text screen
- xor ch,ch
- call putcirc ; save them
- mov ax,linec ; reset the current pointer
- sub ax,1 ; to the previous line
- jge upone1 ; ge = not past end, we're OK
- xor ax,ax ; yup, back up
- upone1: mov linec,ax ; save the results
- call getcirc ; now get the new screen
- clc
- ret
- fupone endp
-
- ; Horizontal scrolling keyboard verbs
- frtpage proc far
- mov cx,20 ; step size
- call rtcommon
- ret
- frtpage endp
-
- frtone proc far
- mov cx,1
- call rtcommon
- ret
- frtone endp
-
- ; Move screen to the right margin by CX columns
- rtcommon proc near
- push bx
- mov bl,byte ptr cursor+1 ; current cursor row
- xor bh,bh
- mov al,linescroll[bx] ; horz scroll in effect for this line
- pop bx
- add al,handhsc ; plus hand scrolling now present
- add al,crt_cols ; right most char on visible screen
- adc ah,0
- cmp ax,vswidth ; too far already?
- ja rtcomm2 ; a = yes, do nothing
- sub ax,vswidth ; available distance
- neg ax
- cmp ax,cx ; space vs desired scroll
- jbe rtcomm1 ; be = less than desired, use space
- mov ax,cx ; enough room, use desired scroll
- rtcomm1:add handhsc,al ; indicate how much done by hand
- call repaint
- rtcomm2:clc
- ret
- rtcommon endp
-
- flfpage proc far
- mov cx,20 ; step size
- call lfcommon
- ret
- flfpage endp
-
- flfone proc far
- mov cx,1 ; step size
- call lfcommon
- ret
- flfone endp
-
- ; Move screen toward left margin by CX columns
- lfcommon proc near
- push bx
- mov bl,byte ptr cursor+1 ; current cursor row
- xor bh,bh
- mov al,linescroll[bx] ; horz scroll in effect for this line
- pop bx
- add al,handhsc ; available distance to move
- jz lfcomm2 ; z = no space to mov
- sub al,cl ; minus out desired jump
- jge lfcomm1 ; ge = no overscroll the wrong way
- add cl,al ; reduce cx request by overage
- lfcomm1:sub handhsc,cl ; successful, new handhsc
- call repaint
- lfcomm2:clc
- ret
- lfcommon endp
-
- ; Scrolling routines. vtscru scrolls up, vtscrd scrolls down 'scroll'
- ; rows. Top lines are saved in the circular buffer before scrolling up.
- ; When running under an Environment control number of line positions moved
- ; to be less than scrolling region.
- ; All registers are preserved.
- ;
- ; Screen scroll up "scroll" lines (text moves up) for terminal emulator use.
-
- vtscru proc near
- push ax
- push bx
- push cx
- push dx
- push si
- push di
- mov al,mar_bot ; compute size of scroll
- sub al,mar_top
- inc al ; lines in scrolling region
- mov dl,scroll ; desired scroll
- xor dh,dh
- cmp dl,al ; scrolling more than needed?
- jbe vtscru1 ; be = no
- mov dl,al ; limit scrolling
- mov scroll,al
- vtscru1:or dl,dl
- jnz vtscru2
- jmp vtscru9 ; z = nothing to do
-
- vtscru2:cmp mar_top,0 ; scrolling the top screen line?
- jne vtscru5 ; ne = no, do not save in roll back
- mov cx,dx ; cx is how many lines
- call putcirc ; put screen lines in circular buffer
-
- add linec,cx ; (BDT) increment the current line
- mov cx,linec ; new current line number
- sub cx,lcnt ; minus # in buf = qty new lines added
- jc vtscru3 ; c = not extending buffer
- add lcnt,cx ; (BDT) increment the line counter
- vtscru3:mov cx,lcnt ; (BDT) check: are we
- cmp cx,lmax ; (BDT) beyond the end?
- jb vtscru5 ; (BDT) b = no
- sub cx,lmax ; (BDT) compute overflow count
- add linef,cx ; (BDT) adjust the "first" line
- mov cx,linef ; (BDT) check: time to wrap?
- cmp cx,linee ; (BDT) ...
- jb vtscru4 ; (BDT) b = no
- sub cx,linee ; (BDT) yup
- mov linef,cx ; (BDT) adjust it
- vtscru4:mov cx,lmax ; (BDT) get the maximum line count
- mov lcnt,cx ; (BDT) reset the line counter
- mov linec,cx ; (BDT) reset the current line
-
- vtscru5:mov di,word ptr vs_ptr ; offset of virtual screen
- mov cl,vswidth
- mov al,mar_top ; top line number (from 0)
- mul cl ; times chars/line
- add ax,ax ; char + attribute
- add di,ax ; destination (mar_top)
- mov al,dl ; number of lines to scroll
- mov cl,vswidth
- mul cl ; vswidth * total lines to scroll
- mov bx,ax ; number of cells to clear
- add ax,ax ; bytes
- mov si,di
- add si,ax ; src is that many bytes down screen
- mov al,mar_bot ; lines in scrolling region
- sub al,mar_top
- inc al
- sub al,dl ; minus scrolled portion
- mul cl ; times words per line
- mov cx,ax ; number of cells to copy
- mov dh,scbattr ; need this for later (in seg data)
- push cx ; save number of words for attribute
- push es
- push ds
- mov ax,word ptr vs_ptr+2 ; segment of vscreen
- mov ds,ax
- mov es,ax
- cld
- rep movsw ; copy src to dest
- mov cx,bx ; count of words to clear
- mov ah,dh ; default attriubte
- mov al,' ' ; filler for clearing a line
- rep stosw ; store after new src
- pop ds
- pop es
- ; bx is number of words cleared
- mov di,word ptr vsat_ptr ; offset of attributes
- mov cl,((vswidth+1)/2)*2 ; char cells per attributes line
- mov al,mar_top ; top line number (from 0)
- mul cl ; times cells per line
- shr ax,1 ; two char's of attributes per byte
- add di,ax ; destination (mar_top)
- mov si,di
-
- mov al,dl ; number of lines to scroll
- mov cl,((vswidth+1)/2)*2 ; cells/line for attributes
- mul cl ; vswidth * total lines to scroll
- mov bx,ax ; number of cells to clear
- shr bx,1 ; was char cells, now use bytes
- add si,bx ; src is that many bytes down screen
- pop cx ; number of vscreen cells copied
- shr cx,1 ; two cells per byte of attributes
- push es
- push ds
- mov ax,word ptr vsat_ptr+2 ; segment of vsatt
- mov ds,ax
- mov es,ax
- cld
- rep movsb ; copy src to dest
- mov cx,bx ; count of bytes to clear
- xor al,al ; default attributes of none
- rep stosb ; store after new src
- pop ds
- pop es
- cmp writemode,0 ; use direct screen writing?
- je vscru5a ; e = yes
- cmp tekflg,tek_active+tek_sg ; special graphics mode?
- jne vscru5b ; ne = no
-
- vscru5a:cmp tekflg,tek_active+tek_sg ; special graphics mode?
- jne vtscru8 ; ne = no
- call tekremcursor ; turn off text cursor
- vscru5b:mov dosetcursor,-1 ; don't turn on automatically
- mov al,' ' ; write space
- mov ah,scbattr ; in normal colors
- xor dl,dl ; at mar_top, left margin
- mov dh,mar_top ; to set normal text mode for the
- cmp tekflg,tek_active+tek_sg ; special graphics mode?
- jne vscru5d ; ne = no
- call ttxtchr ; graphics adapter
- vscru5d:mov ax,0600h ; scroll up whole region
- mov dh,mar_bot ; bottom row
- mov dl,crt_cols
- cmp dl,80 ; more than physical screen?
- jbe vscru5e ; be = no
- mov dl,80
- vscru5e:dec dl ; right most physical col for scroll
- mov ch,mar_top ; top row of scrolling region
- xor cl,cl ; left most column
- mov bh,scbattr ; attributes
- mov bl,dh
- sub bl,ch ; region size - 1 line
- jz vscru2b ; z = region is 1 line, do one scroll
- mov al,scroll ; number of lines to scroll, from msz
- vscru2a:cmp al,bl ; want to scroll more that than?
- jbe vscru2b ; be = no
- push ax
- mov al,bl ; limit to region - 1 for Windows
- int screen ; and do in parts
- pop ax
- sub al,bl ; al = amount yet to scroll
- jmp short vscru2a ; do next part
- vscru2b:int screen ; scroll up that region
- mov dx,cursor
- mov dosetcursor,dx ; reminder of where to set cursor
- jmp short vtscru9
-
- vtscru8:mov dh,mar_bot ; real text mode
- mov dl,mar_top ; setup touchup, lines changed
- call touchup ; touch up real screen
- vtscru9:pop di
- pop si
- pop dx
- pop cx
- pop bx
- pop ax
- ret
- vtscru endp
-
- ; Screen-roll down. Move text down scroll lines, for terminal emulator only.
- vtscrd proc near
- push ax
- push bx
- push cx
- push dx
- push si
- push di
- push bp
- push es
- les si,vs_ptr ; source is top line of virtual screen
- mov al,mar_top ; top margin line (0..)
- mov cl,vswidth ; chars across vscreen
- mul cl
- add ax,ax ; words to bytes
- add si,ax ; offset of start of top line
- mov bp,si ; remember top line for later
- mov cl,mar_bot ; compute number of lines to move
- sub cl,mar_top
- inc cl ; qty of lines in region
- mov ch,scroll
- cmp ch,cl ; want to scroll more than region?
- jbe vtscrd1 ; be = no
- mov ch,cl ; set scroll to whole region
- mov scroll,ch ; remember for attributes
- vtscrd1:sub cl,ch ; less lines to be skipped
- mov bl,ch ; save effective scroll for below
- mov al,vswidth ; number of character cells
- mul cl
- mov cx,ax ; number of words in the movement
- dec ax ; compute to end word
- add ax,ax ; number of bytes
- add si,ax ; go to the end
- mov di,si
- mov al,vswidth ; words in a line buffer
- mul bl ; number of chars dest is below src
- mov bx,ax ; save number of chars here for clear
- add ax,ax ; number of bytes (char + attribute)
- add di,ax ; destination offset
- push ds
- mov ax,es
- mov ds,ax
- std
- rep movsw ; copy down the lines
- cld
- pop ds
- mov di,bp ; fill top line in scrolling region
- mov ah,scbattr
- mov al,' '
- mov cx,bx ; number of char cells to clear
- rep stosw ; fill top line(s) with spaces
- ; do extended attributes the same way
- les si,vsat_ptr ; source of extended attributes
- mov al,mar_top ; top margin line (0..)
- mov cl,((vswidth+1)/2)*2 ; attribute cells/line
- mul cl
- shr ax,1 ; two attributes per byte
- add si,ax ; offset of start of top line
- mov bp,si ; remember top line for later
- mov cl,mar_bot ; compute number of lines to move
- sub cl,mar_top
- inc cl ; qty of lines in region
- mov ch,scroll
- sub cl,ch ; less lines to be skipped
- mov bl,ch ; save effective scroll for below
- mov al,((vswidth+1)/2)*2 ; number of attribute cells/line
- mul cl
- shr ax,1 ; two attributes per byte
- mov cx,ax ; number of bytes in the movement
- dec ax ; compute to end byte
- add si,ax ; go to the end
- mov di,si
- mov al,((vswidth+1)/2)*2 ; number of attribute cells/line
- mul bl ; number of cells dest is below src
- shr ax,1 ; two attributes per byte
- mov bx,ax ; save number of bytes here for clear
- add di,ax ; destination offset
- push ds
- mov ax,es
- mov ds,ax
- std
- rep movsb ; copy down the lines
- cld
- pop ds
- mov di,bp ; fill top line in scrolling region
- xor al,al ; null attributes for filler
- mov cx,bx ; number of attributes bytes to clear
- rep stosb ; fill top line(s) with spaces
- pop es
- pop bp
- cmp writemode,0 ; use direct screen writing?
- je vscrd1 ; e = yes
- cmp tekflg,tek_active+tek_sg ; special graphics mode?
- jne vscrd3a ; ne = no
- vscrd1: cmp tekflg,tek_active+tek_sg ; special graphics mode?
- je vscrd3 ; e = yes
- mov dl,mar_top ; setup touchup, lines changed
- mov dh,mar_bot
- call touchup ; touch up real screen
- jmp short vscrd8
-
- vscrd3: call tekremcursor ; turn off text cursor
- vscrd3a:mov dosetcursor,-1 ; don't turn on automatically
- mov al,' ' ; write space
- mov ah,scbattr ; in normal colors
- xor dl,dl ; at mar_bot, left margin
- mov dh,mar_bot ; to set normal text mode for the
- cmp tekflg,tek_active+tek_sg ; special graphics mode?
- jne vscrd3b ; ne = no
- call ttxtchr ; graphics adapter
- vscrd3b:mov ax,0700h ; scroll down whole region
- mov ch,mar_top ; top margin line
- xor cl,cl ; left most column
- mov dh,mar_bot ; bottom margin line
- mov dl,crt_cols
- cmp dl,80 ; more than physical screen?
- jbe vscrd3c ; be = no
- mov dl,80
- vscrd3c:dec dl ; right most physical col for scroll
- mov bh,scbattr ; attributes
- mov bl,dh
- sub bl,ch ; region size - 1 line
- jz vscrd7 ; z = region is 1 line, do one scroll
- mov al,scroll ; number of lines to scroll, from msz
- vscrd7: cmp al,bl ; want to scroll more that than?
- jbe vscrd2 ; be = no
- push ax
- mov al,bl ; limit to region-1 for Windows
- int screen ; and do in parts
- pop ax
- sub al,bl ; get remainder
- jmp short vscrd7 ; do next part
- vscrd2: int screen ; scroll it down
- mov dx,cursor
- mov dosetcursor,dx ; reminder of where to set cursor
- vscrd8: pop di
- pop si
- pop dx
- pop cx
- pop bx
- pop ax
- ret
- vtscrd endp
-
- ; Put the top cx lines from the virtual screen in to the circular buffer
- ; starting at line index linec (counted from zero, modulo linee).
- putcirc proc near
- jcxz putcir6 ; z = no lines to save
- cmp lmax,0 ; any buffer space?
- jne putcir7 ; ne = yes, have some
- putcir6:ret
- putcir7:push ax
- push bx
- push cx
- push dx
- push si
- push di
- push es
- cld
- mov pageready,-1 ; ems page number currently active
- mov si,word ptr vs_ptr ; offset of screen buffer
- mov bx,linef ; index of the first line
- add bx,linec ; add the current line counter
- dec bx
- putcir1:inc bx
- cmp bx,linee ; at the end of the buffer now?
- jb putcir2 ; b = no
- sub bx,linee ; backup to start of buffer
- putcir2:mov ax,bx ; line index
- call emsfixup ; do expanded memory conversion work
- mul ppl ; times paragraphs per line
- add ax,iniseg ; plus initial seg of buffer
- mov es,ax ; now we have the segment pointer
- xor di,di ; buffer offset is always 0
- push cx ; save the number of lines
- mov cx,rollwidth ; get the number of characters to move
- push si ; save starting vscreen offset
- push ds ; get the offset of the screen
- cld
- mov ds,word ptr vs_ptr+2 ; seg of vscreen
- rep movsw ; move them
- pop ds ; restore DS
- pop si ; vscreen offset
- add si,vswidth*2 ; inc to next vscreen line
- pop cx ; restore the line count
- loop putcir1 ; go back for more
- pop es
- pop di
- pop si
- pop dx
- pop cx
- pop bx
- pop ax
- clc
- ret
- putcirc endp
-
- ; Get CX lines from the circular buffer, non destructively, starting at
- ; line index linec (counted from zero, modulo linee) and put them at
- ; the top of the virtual screen. Fewer lines are written if the buffer
- ; holds fewer than CX.
- getcirc proc near
- or cx,cx ; check on qty
- jnz getcir0 ; nz = some
- ret
- getcir0:push ax
- push bx
- push cx
- push dx
- push si
- push di
- push es
- mov pageready,-1 ; ems page number currently active
- les di,vs_ptr ; seg and offset of vscreen
- mov bx,linef ; get the first line pointer
- add bx,linec ; add the current line counter
- dec bx
- cld
- getcir1:inc bx
- cmp bx,linee ; at the end of the buffer now?
- jb getcir2 ; b = no
- sub bx,linee ; backup to start of buffer
- getcir2:mov ax,bx ; line index
- call emsfixup ; do expanded memory conversion work
- mul ppl ; times paragraphs per line
- add ax,iniseg ; plus initial seg of buffer
- xor si,si ; initial offset is always 0
- push cx ; save the number of lines
- mov cx,rollwidth ; get the number of characters to move
- push di ; save vscreen offset
- push ds ; save DS for a tad
- mov ds,ax ; now we have the segment pointer
- rep movsw ; move them
- pop ds ; restore DS
- pop di ; recover vscreen offset
- add di,vswidth*2 ; next vscreen line
- pop cx ; restore the line count
- loop getcir1 ; go back for more
- call repaint ; repaint screen
- pop es
- pop di
- pop si
- pop dx
- pop cx
- pop bx
- pop ax
- clc
- ret
- getcirc endp
-
- ; Convert rollback line number in AX to line number in ems page, and invoke
- ; that page. Destroys dx, returns ax as line number in page.
- emsfixup proc near
- cmp emsrbhandle,0 ; EMS in use?
- jg emsfix1 ; g = yes (-1 is not in use)
- ret
- emsfix1:xor dx,dx
- div lineems ; line number / lines per ems page
- push bx
- mov bx,ax ; quotient, page number
- mov ax,dx ; remainder, line in page
- cmp bx,pageready ; is this page now present?
- je emsfix2 ; e = yes
- mov pageready,bx ; remember
- push ax
- mov ah,emsmapmem ; map logical page in bx
- xor al,al ; to physical page zero
- mov dx,emsrbhandle ; our ems rollback handle
- int emsint
- pop ax ; return ax as line in page
- emsfix2:pop bx
- ret
- emsfixup endp
-
- ; Repaint screen from the vscreen buffer
- repaint proc near
- push dx
- xor dl,dl ; top row
- mov dh,crt_lins ; physical screen rows-1, incl status
- call touchup
- pop dx
- ret
- repaint endp
-
- ; Repaint part of screen from the vscreen buffer, with linescroll offset
- ; dh is bottom line number, dl is top line number (dh >= dl)
- ftouchup proc far
- call touchup
- ret
- ftouchup endp
-
- touchup proc near ; get lines from virtual screen
- cmp flags.vtflg,ttgenrc ; terminal type of none?
- jne touch1 ; ne = no
- ret
- touch1: push ax
- push bx
- push cx
- push dx
- push si
- push di
- push es
- mov cl,dh ; last row to change
- sub cl,dl ; number of lines -1
- cmp cl,crt_lins ; out of bounds value?
- jbe touch1b ; be = no
- xor cl,cl ; stay sane
- touch1b:inc cl ; number of lines to update
- xor ch,ch
- cmp tekflg,tek_active+tek_sg ; special graphics mode?
- je touch1c ; e = yes, skip text screen update
- test tekflg,tek_active ; other graphics mode?
- jnz touch9 ; nz = yes, no touchup
-
- call scroff ; turn off text screen
- mov es,tv_segs ; get the segment of the screen
- mov di,tv_sego ; initial screen offset
- touch1c:mov al,crt_cols ; physical screen width
- mul dl ; chars into physical screen
- add ax,ax ; chars to bytes
- add di,ax ; offset of start of phy update area
- mov si,word ptr vs_ptr
- mov al,vswidth ; chars per line
- mul dl ; ax = bytes to first vscreen line
- add ax,ax ; chars to bytes
- add si,ax ; si = starting vscreen line offset
- mov bl,dl ; top line number
- xor bh,bh ; index for linescroll
- cld
- push dx
- mov dh,dl ; set row into dh, temporarily
- touch2: push si ; save the current line pointer
- push cx ; save the number of lines
- mov cl,crt_cols ; get the number of characters to move
- xor ch,ch
- mov al,linescroll[bx] ; get horiz scroll for this line
- add al,handhsc ; hand done shift
- xor ah,ah
- add ax,ax ; char cells to words
- add si,ax ; offset into vscreen
- cmp writemode,0 ; use direct writing?
- je touch2a ; e = yes
- cmp tekflg,tek_active+tek_sg ; special graphics mode?
- je touch2a ; e = yes
- call tchbios ; Bios writing
- jmp short touch4
- touch2a:cmp tekflg,tek_active+tek_sg ; special graphics mode?
- jne touch3 ; ne = no
- push es
- mov es,word ptr vs_ptr+2 ; es:si is source of data
- call ttxtline ; display whole line
- pop es
- jmp short touch4
-
- touch3: push ds
- mov ds,word ptr vs_ptr+2 ; segment of vscreen
- rep movsw ; from vscreen+hsc to real screen+0
- pop ds
-
- touch4: pop cx ; restore the line count
- pop si ; restore the buffer counter
- inc bx ; for next line
- add si,vswidth*2 ; point to next line
- inc dh
- loop touch2 ; go back for more
- pop dx
- cmp writemode,0 ; direct screen writing?
- jne touch4a ; ne = no, Bios
- cmp tekflg,tek_active+tek_sg ; special graphics mode?
- jne touch5 ; ne = no
- touch4a:mov ah,byte ptr cursor+1 ; row of cursor
- cmp ah,dl ; cursor before this line?
- jb touch9 ; b = yes, skip cursor
- cmp ah,dh ; cursor after this line?
- ja touch9 ; a = yes, skip cursor
- mov cursorst,0 ; say cursor has been zapped off
- mov dx,cursor
- call setpcur ; reset the cursor
- jmp short touch9 ; and all done here
-
- touch5: cmp tv_mode,0h ; TV active?
- je touch8 ; e = no
- mov cl,dh ; tell Topview/Desqview
- sub cl,dl ; number of lines -1
- cmp cl,crt_lins ; out of bounds value?
- jbe touch7 ; be = no
- xor cl,cl ; stay sane
- touch7: inc cl ; number of lines to update
- mov al,crt_cols ; chars/line
- mul cl
- mov cx,ax ; cx = words changed
- call scrsync ; synch Topview
- touch8: call scron ; turn on the screen
- touch9: pop es
- pop di
- pop si
- pop dx
- pop cx
- pop bx
- pop ax
- ret
- touchup endp
-
- ; Write screen via Bios. Enter with SI pointing at starting screen buffer
- ; offset, dh is current screen row, cx has chars to write across a line.
-
- tchbios proc near
- push bx
- xor bh,bh ; video page zero
- push dx
- mov ah,3
- int screen
- mov temp,dx ; save current cursor
- pop dx
- mov cl,crt_cols
- xor ch,ch
- xor dl,dl ; column zero
- cld
- push ds
- mov ds,word ptr vs_ptr+2 ; source is virtual screen buffer
-
- tchbios1:push cx
- mov ah,2 ; set cursor position to dx
- int screen
- lodsw ; char+attribute
- mov bl,ah ; attribute
- mov cx,1 ; one char
- mov ah,9 ; write char at cursor position
- int screen ; do the Bios Int 10h call
- inc dl ; next column
- pop cx
- loop tchbios1
- pop ds
- push dx
- mov dx,temp ; starting cursor position
- mov ah,2 ; set it back there
- int screen
- pop dx
- pop bx
- ret
- tchbios endp
-
- ; Character write/read and cursor manipulation routines for terminal emulator
- ; All registers other than returned values are preserved.
-
- ; Read char and attributes under virtual cursor (DH = row, DL = column).
- ; Returns AL = character, AH = video attributes, CL = logical attribute bit
- ; pair.
- getatch proc near
- push bx
- push si
- push es
- mov al,vswidth ; width of vscreen line
- mul dh ; count down rows (0..)
- add al,dl ; add column
- adc ah,0
- add ax,ax ; times two for char and attrib
- mov bx,ax ; address subscript
- les si,vs_ptr ; main vscreen
- mov ax,es:[si+bx] ; obtain char and attribute
-
- push ax ; save ah attributes
- mov al,((vswidth+1)/2)*2 ; char cells/line for attributes
- mul dh ; times rows
- add al,dl ; add column
- adc ah,0
- shr ax,1 ; two attributes per byte
- mov bx,ax
- pop ax
- les si,vsat_ptr ; extended attributes
- mov bh,es:[bx+si] ; obtain extended attribute byte
- test dl,1 ; odd column (needs shift)?
- jz getatch1 ; z = no, use lower nibble
- mov cl,4 ; four bits of shift
- shr bh,cl
- getatch1:and bh,0fh ; have four extended attribute bits
- mov cl,bh ; return in cl
- pop es
- pop si
- pop bx
- ret
- getatch endp
-
- ; Set virtual cursor postion
- ; DL = column, DH = row, both counted from 0,0 at upper left corner.
- ; If not displaced, handhsc = 0, then scroll left if virtual > crt_cols.
- ; If displaced, handhsc != 0, then scroll right if virtual < handhsc.
- ; For the D463/D470 only, set carry bit (for setatch) if the cursor is off
- ; the visible screen and horizontal scrolling is disabled.
-
- setpos proc near
- push ax
- push es
- mov ax,40h ; look in Bios work area for phy cur
- mov es,ax
- mov ax,es:[50h] ; page zero cursor postion is here
- pop es
- cmp ax,dx ; same as where we are commanded?
- jne setpos0 ; ne = no, do the work
- pop ax
- ret
- setpos0:push bx
- push cx
- push dx ; save outside virtual cursor
- mov cl,crt_cols ; physical screen width
- push cx ; save here
- cmp inemulator,0 ; emulating?
- je setpos9 ; e = no, no virtual screen
- cmp tekflg,tek_active+tek_sg ; special graphics mode?
- jne setpos1 ; ne = no
- test flags.vtflg,ttd463+ttd470 ; doing DG D463/D470 emulation?
- jz setpos1 ; z = no
- mov bl,dh ; get row
- xor bh,bh
- cmp dgwindcomp[bx],0 ; is this line compressed?
- je setpos1 ; e = no
- mov crt_cols,128 ; DG graphics, 5 dot chars, 128/line
- setpos1:mov ch,vswidth-1 ; leftmost legal margin (207-1)
- sub ch,crt_cols ; minus screen physical width
- xor cl,cl ; cl is flag for repainting needed (if != 0)
- xchg handhsc,cl ; hand-done horiz scroll, clear it
- or cl,cl ; need to undo it?
- jz setpos2 ; z = no
- call repaint ; repaint screen without hand scroll
- xor cl,cl ; remove repaint indicator
- setpos2:mov bl,dh ; current row
- xor bh,bh
- mov ah,linescroll[bx] ; current horz scroll
-
- setpos3:mov al,dl ; virtual column where we ought to be
- sub al,ah ; virtual - already scrolled
- jc setpos4 ; c = cursor off screen to the left
- cmp al,crt_cols ; beyond right physical screen?
- jb setpos5 ; b = no, use this
- mov cl,1 ; say need repaint
- inc ah
- jc setpos3a ; c = over did it
- cmp ah,ch ; going beyond largest scroll?
- jbe setpos3 ; be = no
- setpos3a:mov ah,ch ; yes, stay here
- jmp short setpos5 ; done, do real operation
-
- setpos4:mov cl,1 ; say repaint needed
- mov ah,dl ; reduce horz scroll
-
- setpos5:or cl,cl ; repaint needed?
- jz setpos8 ; z = no
- test flags.vtflg,ttd463+ttd470 ; D463/D470?
- jz setpos5a ; z = no
- cmp dghscrdis,0 ; D463/D470 horz scroll disabled?
- je setpos5a ; e = no, check auto vs manual
- stc ; c = do not show on real screen
- jmp short setposx ; skip screen update
-
- setpos5a:test vtemu.vtflgop,vshscroll ; horizontal scrolling, manual?
- jnz setpos9 ; nz = yes, else auto
-
- setpos5b:mov bl,mar_top ; auto scrolling, top row
- xor bh,bh
- mov cl,mar_bot
- sub cl,bl
- xor ch,ch
- inc cx ; lines in scrolling region
- setpos6:cmp linescroll[bx],ah ; any change?
- je setpos7 ; e = no
- mov linescroll[bx],ah ; set scroll for this line
- push dx
- mov dl,bl
- mov dh,bl
- call touchup ; repaint this line
- pop dx
- setpos7:inc bx
- loop setpos6 ; do all lines in window
-
- setpos7a:push ax ; now do status line
- push si
- mov cl,byte ptr low_rgt+1 ; examine whole screen
- inc cl ; lines in emulation part
- xor ch,ch
- mov bx,cx ; remember for status line
- mov si,offset linescroll
- mov ah,[si] ; smallest horizontal shift found
- cld
- setpos10:lodsb ; current line scroll to al
- cmp al,ah ; smaller than smallest?
- ja setpos11 ; a = no
- mov ah,al ; remember smallest
- or ah,ah ; zero?
- jz setpos11a ; can't get any smaller than this
- setpos11:loop setpos10
-
- setpos11a:cmp linescroll[bx],ah ; status line, need to scroll?
- je setpos12 ; e = already smallest
- mov linescroll[bx],ah ; modify status line
- push dx
- mov dl,bl
- mov dh,bl
- call touchup ; redraw status line
- pop dx
- setpos12:pop si
- pop ax
- setpos8:sub dl,ah ; virtual - horz scrolled column
-
- setpos9:call setpcur ; set physical cursor
- clc ; set status for ok to show
- setposx:pop cx
- mov crt_cols,cl
- pop dx
- pop cx
- pop bx
- pop ax
- ret
- setpos endp
-
- ; Read physical cursor position
- ; DL = column, DH = row, both counted from 0,0 at upper left corner
- ; CX = cursor lines
- getpcur proc near
- push ax
- push bx
- mov ah,3 ; get cursor position
- xor bh,bh ; page 0
- int screen
- pop bx
- pop ax
- ret
- getpcur endp
-
- fgetpcur proc far
- call getpcur
- ret
- fgetpcur endp
-
- ; Set physical cursor postion
- ; DL = column, DH = row, both counted from 0,0 at upper left corner
- setpcur proc near
- push dx
- cmp dl,crt_cols ; out of bounds?
- jb setpcur1 ; b = ok
- mov dl,crt_cols ; physical cols on screen
- dec dl ; count from zero
- setpcur1:cmp inemulator,0 ; emulating?
- je setpcur4 ; e = no, no virtual screen
- cmp tekflg,tek_active+tek_sg ; special graphics mode?
- jne setpcur4 ; ne = no
- push ax
- push es
- mov ax,40h
- mov es,ax
- mov ax,es:[50h] ; current position
- mov es:[50h],dx ; text page 0 cursor, keep it tracking
- cmp ax,dx ; same?
- pop es
- pop ax
- jne setpcur2 ; not same, draw cursor
- cmp cursorst,0 ; is cursor off now?
- jne setpcur3 ; ne = no, skip redrawing
- setpcur2:mov dosetcursor,dx ; reminder of where to set cursor
- call tekremcursor ; ensure it's off
- setpcur3:pop dx
- ret
-
- setpcur4:push ax
- push es
- mov ax,40h
- mov es,ax
- mov ax,es:[50h] ; current position
- cmp ax,dx ; same?
- pop es
- jne setpcur5 ; ne = no
- pop ax
- pop dx
- ret
- setpcur5:push bx
- mov ah,2 ; set cursor
- xor bh,bh ; page 0
- int screen
- pop bx
- pop ax
- pop dx
- ret
- setpcur endp
-
- ; Read char and attributes under physical cursor.
- ; Returns AL = character, AH = video attributes
- getpcha proc near
- push bx
- mov ah,8 ; read char and attributes
- xor bh,bh ; page 0
- int screen ; Bios video call
- pop bx
- ret
- getpcha endp
-
- ; Write char and attribute to screen at cursor position, do not move cursor.
- ; AL = char, AH = video attribute, DL = column, DH = row, CL = logical
- ; attribute bits. Does not update physical screen.
- qsetatch proc near
- mov setnoshow,1 ; turn off physical screen update
- jmp setatch ; call with same args
- qsetatch endp
-
- ; Write char and attribute to screen at cursor position, do not move cursor.
- ; AL = char, AH = video attribute, DL = column, DH = row, CL = logical
- ; attribute bits. Turns off setnoshow at the end.
-
- setatch proc near
- push bx
- push es
- push cx ; save logical attribute
- push ax ; save char and attribute
- cmp setnoshow,0 ; show on real screen?
- jne setatc1 ; ne = no, do just virtual screen
- call setpos ; set cursor at dx location
- jc setatc1 ; c = do not show character
- cmp inemulator,0 ; emulating a terminal now?
- je setatc4 ; e = no
- cmp tekflg,tek_active+tek_sg ; special graphics mode?
- jne setatc4 ; ne = no, text mode
- push dx
- push si
- push di
- mov bl,dh ; get row
- xor bh,bh
- sub dl,linescroll[bx] ; deduct horizontal scroll
- call ttxtchr ; display char in graphics mode
- pop di
- pop si
- pop dx
- jmp short setatc1
- setatc4:
- mov cx,1 ; one char
- mov bl,ah ; attribute
- xor bh,bh ; page 0
- mov ah,9 ; write char, do not move cursor
- int screen
- setatc1:mov setnoshow,0 ; always reset this automatically
- ; write same material to vscreen
- mov al,vswidth ; width of vscreen line
- mul dh ; count across rows (0..)
- xor bh,bh
- mov bl,dl ; get position
- add bx,ax ; add column
- add bx,bx ; times two for char and attrib
- pop ax ; recover char and attribute
- pop cx ; recover logical attribute
- cmp inemulator,0 ; in terminal emulator?
- je setatc2 ; e = no, so no virtual screen
- push di
- les di,vs_ptr ; virtual screen
- mov es:[di+bx],ax ; store char and attribute
- push ax ; save ah attributes
- mov al,((vswidth+1)/2)*2 ; char cells/line for attributes
- mul dh ; times rows
- add al,dl ; add column
- adc ah,0
- shr ax,1 ; two attributes per byte
- mov bx,ax
- les di,vsat_ptr ; attributes nibble array
- mov al,es:[bx+di] ; get two nibbles
- mov ah,cl ; save extended attribute nibble
- xor cl,cl ; shift amount, assume zero
- test dl,1 ; is this an odd column?
- jz setatc3 ; z = no
- mov cl,4 ; use only four lowest order bits
- setatc3:ror al,cl ; bring pair to low order
- and al,not 0fh ; remove old
- and ah,0fh ; just the new
- or al,ah ; put new in place
- rol al,cl ; rotate back
- mov es:[bx+di],al ; store again
- pop ax
- pop di
- setatc2:pop es
- pop bx
- ret
- setatch endp
-
- ; Get bold video attribute bit
- ; Returns AH = bold attribute bit (0 if not bold)
- getbold proc near
- and ah,att_bold
- test flags.vtflg,ttd463+ttd470 ; D463/D470?
- jnz getbold1 ; nz = yes
- xor ah,userbold ; invert with user bold
- getbold1:ret
- getbold endp
-
- ; Set bold video attribute bit, current video attribute supplied in AH
- setbold proc near
- or ah,att_bold
- test flags.vtflg,ttd463+ttd470 ; D463/D470?
- jnz setbold1 ; nz = yes
- xor ah,userbold ; invert with user bold
- setbold1:ret
- setbold endp
-
- ; Clear bold video attribute bit, current video attribute supplied in AH
- clrbold proc near
- and ah,not att_bold
- test flags.vtflg,ttd463+ttd470 ; D463/D470?
- jnz clrbold1 ; nz = yes
- or ah,userbold ; invert with user bold
- clrbold1:ret
- clrbold endp
-
- ; Get blink video attribute bit
- ; Returns AH = blink attribute bit
- getblink proc near
- and ah,att_blink
- ret
- getblink endp
-
- ; Set blink video attribute bit, current video attribute supplied in AH
- setblink proc near
- or ah,att_blink
- ret
- setblink endp
-
- ; Clear blink video attribute bit, current video attribute supplied in AH
- clrblink proc near
- and ah,not att_blink
- ret
- clrblink endp
-
- ; Set extended attribute for protection in extattr and in CL.
- setprot proc near ; set protected mode
- or extattr,att_protect
- or cl,att_protect ; and in cl
- ret
- setprot endp
-
- ; Clear extended attribute for protection in extattr and in CL.
- clrprot proc near ; clear protected mode
- and extattr,not att_protect
- and cl,not att_protect
- ret
- clrprot endp
-
- ; Get underline video attribute bit from extattr
- ; Returns CL = underline attribute bit
- getunder proc near
- mov cl,extattr ; get extended attribute
- and cl,att_uline ; return underline status bit
- ret
- getunder endp
-
- ; Set underline video attribute bit, current video attribute supplied in AH
- ; and extended attributes in extattr. Returns new AH and extattr in CL.
- setunder proc near
- test extattr,att_uline ; extended attributes, on already?
- jz setund1 ; z = no
- ret ; else do nothing
- setund1:or extattr,att_uline ; set underline attribute for MSZ
- or cl,att_uline
- cmp crt_mode,7 ; monochrome display adapter mode?
- je setund6 ; e = yes, otherwise xor video
- push bx
- push dx
- mov bh,al ; preserve possible char in al
- mov dl,scbattr ; screen fill
- and dl,70h ; background colors
- mov bl,extattr ; extended attributes
- and bl,att_rev ; per char reversed video
- mov dh,ah ; current character attributes
- and dh,not 77h ; blink/bold attributes only
- and ah,77h ; colors only
- mov al,ah
- shr al,1
- shr al,1
- shr al,1
- shr al,1 ; background to lower nibble
- and ah,7 ; foreground only
- or bl,bl ; reversed video attribute?
- jz setund3 ; z = no, normal
- xchg ah,al ; real background color to al
- setund3:xor al,ah ; modify background
- or dl,dl ; case of black background?
- jnz setund4 ; nz = no
- mov al,ah
- dec al
- and al,7 ; background goes to (foreground-1)/8
- or al,al ; still black?
- jnz setund4 ; nz = no
- mov al,7 ; force non-black (white foreground)
- setund4:shl al,1 ; background to high nibble
- shl al,1
- shl al,1
- shl al,1
- or ah,al ; or new background
- or bl,bl ; per char reversal?
- jz setund5 ; z = no
- rol ah,1 ; yes, flip fore/background again
- rol ah,1
- rol ah,1
- rol ah,1
- setund5:or ah,dh ; restore blink and bold
- pop dx
- mov al,bh ; restore possible char
- pop bx
- ret
- setund6:call brkatt ; break apart attributes
- or al,att_uline ; set underline bit
- call addatt ; reassemble attributes into ah
- ret
- setunder endp
-
- ; Clear underline video attribute bit, current video attribute supplied in AH
- ; and extended attributes in extattr. Returns new AH and extattr in CL.
- clrunder proc near
- test extattr,att_uline ; extended attributes, off already?
- jnz clrund1 ; nz = no
- ret ; else do nothing
- clrund1:and extattr,not att_uline ; clear underline attribute for MSZ
- and cl,not att_uline
- cmp crt_mode,7 ; monochrome display adapter mode?
- je clrund6 ; e = yes, otherwise reverse video
- push bx
- push dx
- mov bh,al ; save possible char in al
- xor bl,bl
- mov dl,scbattr ; screen fill
- and dl,70h ; background colors
- mov bl,extattr ; extended attributes
- and bl,att_rev ; per char reversed video
- mov dh,ah ; current char attributes
- and dh,not 77h ; blink/bold attributes only
- and ah,77h ; colors only
- mov al,ah
- shr al,1
- shr al,1
- shr al,1
- shr al,1 ; background to lower nibble
- and ah,7 ; foreground only
- or bl,bl ; reversed video attribute?
- jz clrund3 ; z = no, normal
- xchg ah,al ; real background color to al
- clrund3:or dl,dl ; case of black background?
- jz clrund4 ; z = yes, leave it black (empty)
- xor al,ah
- shl al,1 ; background to high nibble
- shl al,1
- shl al,1
- shl al,1
- or ah,al ; or in new background
- clrund4:or bl,bl ; per char reversal?
- jz clrund5 ; z = no
- rol ah,1 ; yes, reverse nibbles again
- rol ah,1
- rol ah,1
- rol ah,1
- clrund5:or ah,dh ; restore blink and bold
- pop dx
- mov al,bh ; restore possible char
- pop bx
- ret
- clrund6:call brkatt ; break apart attributes
- and al,not att_uline ; turn off underline bit
- call addatt ; reassemble attributes
- ret
- clrunder endp
-
- ; Compute reversed video attributes, given displayables in AH and extended
- ; in extattr. Returns new attribute in AH and CL holding new extattr
- setrev proc near
- test extattr,att_rev ; reversed now?
- jnz setrev1 ; nz = yes
- call revideo ; do reversal
- or extattr,att_rev ; update extended attribute
- or cl,att_rev
- setrev1:ret
- setrev endp
-
- ; Compute un-reversed video attributes, given displayables in AH and extended
- ; in extattr. Returns new attribute in AH and CL holding new extattr
- clrrev proc near
- test extattr,att_rev ; reversed now?
- jz clrrev1 ; z = no
- call revideo ; do reversal
- and extattr,not att_rev ; update extended attribute
- and cl,not att_rev ; update extended attribute
- clrrev1:ret
- clrrev endp
-
-
- ; Compute reversed video attribute byte. Normally preserves blink/bold.
- ; Enter with AH = video attribute byte, returns new attribute byte in AH.
- revideo proc near
- call brkatt ; separate colors from blink/bold
- rol ah,1 ; reverse foreground & background
- rol ah,1 ; RGB bits
- rol ah,1
- rol ah,1
- call addatt ; reinsert bold/blink bits
- ret
- revideo endp
-
- ; This routine picks an attribute apart into its component "parts" - the
- ; base attribute for the screen and the "extras" - i.e., blink, intensity
- ; and underline.
- ; enter with ah = a cursor attribute
- ; return ah = base attribute for screen (07H normal, 70H reverse).
- ; al = "extra" attributes
- ; Note that there is a complementary routine, addatt, for putting attributes
- ; back together.
-
- brkatt: mov al,ah ; copy displayables
- and al,(att_blink+att_bold) ; get modifiers
- and ah,not (att_bold+att_blink) ; strip blink/bold, leave color
- cmp crt_mode,7 ; monochrome display adapter mode?
- jne brkat2 ; ne = no, cut this short for color
- test ah,att_low_mask ; are any of these on?
- jnz brkat1 ; nz = yes, can't be underline
- test ah,att_underline ; underline?
- jz brkat2 ; z = no, some kind of reverse video
- or al,att_underline ; say underline
- test ah,70h ; reverse video + underline?
- jz brkat1 ; z = no, fix up low nibble
- and ah,not 07h ; clear the underline bit in ah
- ret
- brkat1: or ah,att_normal ; normal, turn on all normal bits
- brkat2: ret
-
- ; This routine builds a cursor attribute given the base attribute for the
- ; screen background and the "extra" attributes we want (blink, etc.).
- ; enter with ah = base attribute for background (07H or 70H)
- ; al = "extra" attributes (89H for all three)
- ; return ah = base combined with "extras".
-
- addatt: test al,att_underline ; want underline?
- jz addat1 ; z = no, no need for hack
- cmp crt_mode,7 ; monochrome display adapter mode?
- jne addat1 ; ne = no, cut this short for color
- and ah,not att_low_mask ; clear background colors
- addat1: or ah,al ; Or in the attributes
- ret
-
-
- ; This routine is called when we want to reverse everything on the screen
- ; from normal to reverse video, or vice versa. It is called only when
- ; the decscnm attribute is changed.
- ; Call: no arguments.
-
- revscn proc near
- push ax
- push bx
- push cx
- push dx
- mov dh,byte ptr low_rgt+1 ; compute last screen offset in ax
- inc dh ; one more row to catch mode line
- mov dl,vswidth ; logical screen buffer
- dec dl ; and we count from 0
- call scrloc ; get screen offset into ax
- mov cx,ax ; save it in cx for a minute
- add cx,2
- sar cx,1 ; in 16-bit words please
- push di ; Save some more acs
- push es
- les di,vs_ptr ; seg and offset of vscreen
- cld
- revsc1: mov ax,es:[di] ; fetch a word
- mov bl,al ; save the character
- call revideo ; get reversed video attributes (AH)
- call addatt ; put attributes back together
- mov al,bl ; restore character
- stosw ; stuff into screen memory
- loop revsc1 ; loop for entire screen
- pop es ; restore segment register
- pop di ; and destination index
- pop dx
- pop cx
- pop bx
- call repaint
- pop ax
- ret
- revscn endp
-
- ; Set coloring attributes.
- ; Enter with AH holding current video attribute byte,
- ; BL holding ANSI color code (30-37 or 40-47) where 30's are foreground,
- ; 40's are background. ANSI colors are 1 = red, 2 = green, 4 = blue.
- ; Return new attribute byte in AH.
-
- setcolor proc near
- test extattr,att_rev ; normal video currently?
- jz setcol0 ; z = yes
- mov al,ah ; make a copy
- and ax,7788h ; strip bold,blink, keep both in al
- rol ah,1 ; get colors in right parts
- rol ah,1 ; of ah = back, al = foreground
- rol ah,1
- rol ah,1
- call setcol0 ; set fore or background color
- rol ah,1 ; reverse coloring again
- rol ah,1
- rol ah,1
- rol ah,1
- or ah,al ; put back blink and bold
- ret
-
- setcol0:cmp bl,30 ; ANSI color series?
- jb setcol7 ; b = no
- cmp bl,37 ; foreground set (30-37)?
- ja setcol4 ; a = no, try background set
- sub bl,30 ; take away the bias
- and ah,not 07H ; clear foreground bits
- test bl,1 ; ANSI red?
- jz setcol1 ; z = no
- or ah,4 ; IBM red foreground bit
- setcol1:test bl,2 ; ANSI & IBM green?
- jz setcol2 ; z = no
- or ah,2 ; IBM green foreground bit
- setcol2:test bl,4 ; ANSI blue?
- jz setcol3 ; z = no
- or ah,1 ; IBM blue foreground bit
- setcol3:ret
-
- setcol4:cmp bl,40 ; background color set?
- jb setcol7 ; b = no
- cmp bl,47 ; background set is 40-47
- ja setcol7 ; nb = no, not a color command
- sub bl,40 ; take away the bias
- and ah,not 70H ; clear background bits
- test bl,1 ; ANSI red?
- jz setcol5 ; z = no
- or ah,40h ; IBM red background bit
- setcol5:test bl,2 ; ANSI & IBM green?
- jz setcol6 ; z = no
- or ah,20h ; IBM green background bit
- setcol6:test bl,4 ; ANSI blue?
- jz setcol7 ; z = no
- or ah,10h ; IBM blue background bit
- setcol7:ret
- setcolor endp
-
- ; Save terminal emulator, session is in BX.
- ; Delete older save buffer for this session, so that compressed vscreen
- ; can be saved properly.
- termswapout proc far
- cmp bx,6 ; legal session number?
- jb termso0 ; b = yes
- stc
- ret
- termso0:push ax
- push bx
- push cx
- push si
- push di
- shl bx,1 ; to words
- mov temp,bx ; save session ident
- cmp tsave[bx],0 ; have a storage buffer?
- je termso9 ; ne = no, create one now
- shr bx,1 ; get original BL session indicator
- call termswapdel ; delete old save area
- shl bx,1 ; restore word indexing
- termso9:call getvssize ; get size of vscreen, compressed
- mov ax,bx ; save bx
- call getvasize ; size of attributes
- add bx,ax
- add bx,savexlen ; plus length of MSX save area
- add bx,saveylen ; plus MSY save area
- add bx,savezlen ; plus MSZ area
- add bx,saveplen ; plus parser in MSSCMD
- add bx,saveulen ; plus MSU area
- add bx,saveglen ; plus MSG area
- add bx,15 ; round up
- mov cl,4
- shr bx,cl ; convert to paragraphs
- mov cx,bx ; save request in cx
- mov ah,alloc ; please, more space
- int dos ; paragraph to ax, num paras to bx
- cmp bx,cx ; given vs wanted
- jae termso1 ; ae = got it
- pop di
- pop si
- pop cx
- pop bx
- pop ax
- stc ; fail
- ret
- termso1:
- push temp
- push ax
- call tekend ; exit graphics mode
- pop ax
- pop temp
- mov bx,temp ; get session number (sescur)
- mov tsave[bx],ax ; save starting paragraph
- push es
- mov cx,ds
- mov es,cx
- mov cx,size flginfo ; length of saved flags array
- mov di,offset saveflag ; saved array
- mov si,offset flags ; working array
- rep movsb ; restore
- mov ax,tsave[bx] ; starting paragraph for save area
- mov es,ax ; save area is destination
- xor di,di ; offset of save area
-
- ; virtual screen is saved as structure
- ; scr-len dw text screen length (typically 24 lines)
- ; with the items below repeated for each line (scr-len total lines)
- ; per-line dw saved chars on this line
- ; dw per-line dup (char & attribute)
- ; with the last saved char on each line being repeated to endofline on screen
- push bx ; virtual screen saving
- mov cl,byte ptr low_rgt+1 ; number of text lines - 1
- inc cl
- cmp flags.modflg,2 ; is mode line owned by host?
- jne termso3a ; ne = no
- inc cl ; yes, add it to the save material
- termso3a:xor ch,ch
- mov ax,cx
- cld
- stosw ; store screen length as first word
- xor bx,bx ; line counter
- mov si,word ptr vs_ptr ; offset of vscreen
- termso3:push cx ; save line loop counter
- mov cx,word ptr rdbuf[bx] ; get number of saveable chars on line
- mov ax,cx ; store char count as first word
- stosw
- mov ax,word ptr vs_ptr+2 ; get vscreen segment
- push si
- push ds
- mov ds,ax
- rep movsw ; copy saveable chars
- pop ds
- pop si
- pop cx ; recover line counter
- add bx,2 ; next line, get length info
- add si,vswidth*2 ; next line, offset of vscreen line
- loop termso3
- pop bx ; end of vscreen saving
- ;
- push bx ; virtual screen saving
- mov cl,byte ptr low_rgt+1 ; number of text lines - 1
- inc cl
- cmp flags.modflg,2 ; is mode line owned by host?
- jne termso3b ; ne = no
- inc cl ; yes, add it to the save material
- termso3b:xor ch,ch
- mov ax,cx
- cld
- stosw ; store screen length as first word
- xor bx,bx ; line counter
- mov si,word ptr vsat_ptr ; offset of vsattr
- termso7:push cx ; save line loop counter
- mov cx,word ptr rdbuf[bx+120]; get num of saveable bytes on line
- mov ax,cx ; store char count as first word
- stosw
- mov ax,word ptr vsat_ptr+2 ; get vsattr segment
- push si
- push ds
- mov ds,ax
- shr cx,1 ; get odd byte count info
- jnc termso7a ; nc = even count
- movsb
- termso7a:rep movsw ; copy saveable bytes
- pop ds
- pop si
- pop cx ; recover line counter
- add bx,2 ; next line, get length info
- add si,(vswidth+1)/2 ; next line, offset of vsattr line
- loop termso7
- pop bx ; end of vsattr saving
- ;
- mov si,offset saveyoff ; offset of MSY save area
- mov cx,saveylen ; length of MSY save area
- cld
- shr cx,1 ; even/odd?
- jnc termso4 ; nc = even
- movsb ; the odd byte
- termso4:rep movsw
- mov si,offset savezoff ; offset of MSZ save area
- mov cx,savezlen ; length of MSZ save area
- shr cx,1
- jnc termso5
- movsb
- termso5:rep movsw
- mov si,offset savexoff ; offset of MSX save area
- mov cx,savexlen ; length of MSX save area
- cld
- cli ; cautious about serial ints
- shr cx,1 ; even/odd?
- jnc termso6 ; nc = even
- movsb ; the odd byte
- termso6:rep movsw
- sti
- mov si,offset savepoff ; offset of MSSCMD parser save area
- mov cx,saveplen ; length of the area
- shr cx,1
- jnc termso6a
- movsb
- termso6a:rep movsw
- mov si,offset saveuoff ; offset of MSUIBM kbd save area
- mov cx,saveulen ; length of the area
- shr cx,1
- jnc termso6b
- movsb
- termso6b:rep movsw
- mov si,offset savegoff ; offset of MSG save area
- mov cx,saveglen ; length of MSG save area
- shr cx,1 ; graphics mode exited above
- jnc termso6c
- movsb
- termso6c:rep movsw
- pop es
- mov ax,100h ; assume using 80 col screen
- cmp dos_cols,80 ; startup screen width
- jbe termso8 ; be = assume 80 columns
- inc al ; say do 132 columns
- termso8:push vtemu.vtflgop
- or vtemu.vtflgop,vscompress ; turn off compressed mode
- call chgdsp ; reset display width to startup
- pop vtemu.vtflgop
- pop di
- pop si
- pop cx
- pop bx
- pop ax
- clc
- ret
- termswapout endp
-
- ; Restore terminal emulator, session is BX
- ; Delete save buffer after restoration.
- termswapin proc far
- cmp bx,6 ; valid session?
- jb termsi0 ; b = yes
- stc
- ret
- termsi0:push bx
- shl bx,1 ; to words
- cmp tsave[bx],0 ; have a storage buffer?
- pop bx
- jne termsi1 ; ne = yes, use it
- mov vtinited,0 ; say not inited
- stc ; fail
- ret
-
- termsi1:push ax
- push bx
- push cx
- push si
- push di
- push es ; virtual screen restore
- test tekflg,tek_active ; current graphics mode status
- jz tswapin1a ; z = not in graphics mode
- push bx
- call tekend
- pop bx
- tswapin1a:
- les di,vs_ptr ; seg and offset of vscreen
- shl bx,1 ; to words
- mov ax,tsave[bx] ; starting paragraph of save area
- push ds
- mov ds,ax ; source segment is save area
- xor si,si ; source offset is always zero
- cld
- lodsw ; get screen length
- mov cx,ax ; counter of vscreen lines to do
- tswapi2:push cx ; save line counter
- lodsw ; get count of saved chars of line
- dec ax ; omit repeated char til next step
- mov cx,ax ; count for saved char writes
- rep movsw ; copy saved chars except last one
- mov cx,vswidth ; total line width (chars)
- sub cx,ax ; minus those done
- lodsw ; get last char (this repeats to end)
- rep stosw ; repeat last char
- pop cx ; recover line counter
- loop tswapi2 ; do all text lines (omit status)
- pop ds ; restore DS, SI is ready for nxt grp
- ; end of virtual screen restoration
- ; attributes, vsatt, for vscreen
- les di,vsat_ptr ; seg and offset of vsatt
- mov ax,tsave[bx] ; starting paragraph of save area
- push ds
- mov ds,ax ; source segment is save area
- lodsw ; get screen length
- mov cx,ax ; counter of vsattr lines to do
- tswapi7:push cx ; save line counter
- lodsw ; get count of saved bytes of line
- dec ax ; omit repeated byte til next step
- mov cx,ax ; count for saved byte writes
- shr cx,1 ; do odd byte copy
- jnc tswapi7a ; nc = even count
- movsb
- tswapi7a:rep movsw ; copy saved bytes except last one
- mov cx,(vswidth+1)/2 ; total line width (bytes)
- sub cx,ax ; minus those done
- lodsb ; get last byte (this repeats to end)
- rep stosb ; repeat last byte
- pop cx ; recover line counter
- loop tswapi7 ; do all text lines (omit status)
- pop ds ; restore DS, SI is ready for nxt grp
- ; end of virtual screen restoration
-
- mov ax,ds ; regular data seg "data"
- mov es,ax ; new data seg
- mov di,offset saveyoff ; offset of MSY save area
- mov cx,saveylen ; length of MSY save area
- mov ax,tsave[bx] ; starting paragraph of save area
- push ds
- mov ds,ax ; source segment is save area
- cld
- shr cx,1 ; even/odd?
- jnc termsi3 ; nc = even
- movsb ; the odd byte
- termsi3:rep movsw
- mov di,offset savezoff ; offset of MSZ save area
- mov cx,es:savezlen ; length of MSZ save area
- shr cx,1
- jnc termsi4
- movsb
- termsi4:rep movsw
- mov di,offset savexoff ; offset of MSX save area
- mov cx,es:savexlen ; length of MSX save area
- cli ; cautious about serial ints
- shr cx,1
- jnc termsi5
- movsb
- termsi5:rep movsw
- sti
- mov di,offset savepoff ; offset of MSSCMD parser area
- mov cx,es:saveplen ; length
- shr cx,1
- jnc termsi6
- movsb
- termsi6:rep movsw
- mov di,offset saveuoff ; offset of MSUIBM kbd area
- mov cx,es:saveulen ; length
- shr cx,1
- jnc termsi6a
- movsb
- termsi6a:rep movsw
- mov di,offset savegoff ; offset of MSGIBM area
- mov cx,es:saveglen ; length
- shr cx,1
- jnc termsi8
- movsb
- termsi8:rep movsw
- pop ds
- mov cx,ds
- mov es,cx
- mov cx,size flginfo ; length of saved flags array
- mov si,offset saveflag ; saved array
- mov di,offset flags ; working array
- rep movsb ; restore
- mov ah,savattr ; get saved coloring
- mov scbattr,ah ; replace what DOS may have used
- and tekflg,not tek_active ; say graphics is not active
- pop es
- pop di
- pop si
- pop cx
- pop bx
- pop ax
- call termswapdel ; delete this saved area, BL=session
- clc
- ret
- termswapin endp
-
- ; Remove saved terminal emulator buffers, BX is sescur (-1 means all)
- termswapdel proc far
- push ax
- push bx
- shl bx,1 ; to words
- xor ax,ax ; clearing indicator
- xchg ax,tsave[bx] ; paragraph of save area
- or ax,ax ; anything there?
- jnz tswapd1 ; nz = yes
- pop bx
- pop ax
- stc ; fail
- ret
- tswapd1:push es
- mov es,ax ; set paragraph to es for DOS
- mov ah,freemem
- int dos
- pop es
- pop bx
- pop ax
- clc ; succeed
- ret
- termswapdel endp
-
- ; Examine vscreen line by line. Count number of characters by excluding the
- ; trailing repetitions (keep first example) on each line, sum them. Add to
- ; the sum a word per line to hold the count of such characters and one more
- ; word to hold the screen length.
- ; Return the number of bytes in register bx for malloc-ing.
- getvssize proc near
- push cx
- push dx
- push di
- push es
- les di,vs_ptr ; pointer to vscreen
- xor bx,bx ; line counter
- mov cl,crt_lins ; lines on screen
- xor ch,ch
- mov dx,cx ; accumulated count <cnt, line>
- inc dx ; count screen size word itself
- add di,(vswidth - 1) * 2 ; offset of last char on the line
- getvssi1:push cx ; save line counter
- mov cx,vswidth-1 ; chars on line - 1
- mov ax,es:[di] ; get last char+attrib on the line
- push di
- sub di,2
- std ; scan backward
- repe scasw ; scan while equal (trim trailing rpt)
- cld
- pop di
- je getvssi2 ; e = ended on all same char
- inc cx ; ne case gobbles extra char
- getvssi2:inc cx ; count the trailing char
- mov word ptr rdbuf[bx],cx ; store number of words here
- add dx,cx ; accumulate count of chars
- add bx,2 ; next line
- add di,vswidth*2 ; end of next line
- pop cx ; line counter
- loop getvssi1
-
- add dx,dx ; chars to bytes accumulated
- mov bx,dx ; return it in bx
- pop es
- pop di
- pop dx
- pop cx
- ret
- getvssize endp
-
- ; Examine vsattr line by line. Count number of attributes by excluding the
- ; trailing repetitions (keep first example) on each line, sum them. Add to
- ; the sum a word per line to hold the count of such characters and one more
- ; word to hold the screen length. Stores temp length indicator in
- ; words rdbuf+120 et seq (one word per line).
- ; Return the number of bytes in register bx for malloc-ing.
- getvasize proc near
- push ax
- push cx
- push dx
- push di
- push es
- les di,vsat_ptr ; pointer to vsattr
- xor bx,bx ; line counter
- mov cl,byte ptr low_rgt+1 ; lines on normal screen - 1
- add cl,2 ; include status line
- xor ch,ch
- mov dx,cx ; accumulated count <cnt, line>
- inc dx ; count screen size word itself
- add dx,dx ; convert to bytes used
- add di,(((vswidth+1)/2) -1) ; offset of last attrib on the line
- getvasi1:push cx ; save line counter
- mov cx,(((vswidth+1)/2) -1) ; bytes on line - 1
- mov ax,es:[di] ; get last attribute byte on the line
- push di
- dec di
- std ; scan backward
- repe scasb ; scan while equal (trim trailing rpt)
- cld
- pop di
- je getvasi2 ; e = ended on all same byte
- inc cx ; ne case gobbles extra byte
- getvasi2:inc cx ; count the trailing byte
- mov word ptr rdbuf[bx+120],cx; store number of bytes here
- add dx,cx ; accumulate count of bytes
- add bx,2 ; next line
- add di,(vswidth+1)/2 ; end of next line
- pop cx ; line counter
- loop getvasi1
- mov bx,dx ; return bytes needed in bx
- pop es
- pop di
- pop dx
- pop cx
- pop ax
- ret
- getvasize endp
-
- ;
- ; CHKDSP - procedure to check for hardware support of 132 cols
- ; Supported hardware:
- ; ATI EGA and VGA Wonder
- ; AT&T
- ; Everex Viewpoint EV-659, FVGA-673, EV-678, Micro Enhancer Deluxe
- ; IBM XGA
- ; Paradise AutoSwitch EGA Mono, VGA Professional, VGA Plus, VGA Plus 16
- ; STB VGA/EM (Tseng TVGA)
- ; STB VGA/EM Plus (Tseng 4000), VGA/EM-16, VGA/EM-16 Plus
- ; Tseng Labs EVA board w/132-col kit installed
- ; Tseng Labs UltraPAK mono/Herc board w/132 column modes.
- ; Tseng Labs ET4000 SVGA.
- ; VESA compatible Bios'.
- ; Video 7 Vega Deluxe w/ 132X25.COM driver installed and VGA board.
- ; The routine checks for the presence of a 132-column-capable adapter. If
- ; one is found its handler executes the desired mode setting and returns
- ; carry clear; it returns carry set otherwise.
- ; Adding new boards - place an identification string in the data segment,
- ; construct a mode setting routine and insert it in the call list below
- ; (setting 132 column mode is byte AL non-zero). Byte AH is non-zero to
- ; avoid saving old screen and running scrini; it is used to set the screen
- ; width when starting/exiting Connect mode
- ;
- chgdsp proc near
- or al,al ; 80 column mode?
- jnz chgdsg1 ; nz = no, want 132 cols
- test tekflg,tek_active ; graphics mode active?
- jz chgdsp_start ; z = no
- push ax
- push dx
- call tekend ; exit special graphics
- call scrmod ; update video mode info
- pop dx
- pop ax
- jmp short chgdsp_start ; set 80 col mode
-
- chgdsg1:test vtemu.vtflgop,vscompress ; allowed to use graphics for it?
- jnz chgdsp_start ; nz = no, use 132 column text mode
- cmp tekflg,tek_active+tek_sg ; special graphics mode active?
- je chgdsg3 ; e = yes, no change needed
- mov cl,byte ptr low_rgt+1 ; examine whole screen
- add cl,2 ; lines in emulation part + status
- xor ch,ch
- xor bx,bx
- chgdsg2:mov dgwindcomp[bx],1 ; set compressed mode flag non-zero
- inc bx
- loop chgdsg2
- call dgsettek ; setup special graphics mode
- mov byte ptr low_rgt,131 ; 132 columns in special graphics
- mov crt_cols,128 ; but 128 physical columns
- chgdsg3:ret
-
- chgdsp_start:
- push es ; save all we use
- push ax
- push bx
- push cx
- push dx
- push si
- push di
- mov temp,ax ; save set/reset flag from msz
- mov ax,sp ; do push sp test for XT vs AT/386
- push sp ; XT pushes sp-2, AT's push old sp
- pop cx ; recover pushed value, clean stack
- xor ax,cx ; same?
- jne chgdspnw ; ne = no, XT. Don't do Int 2fh
- test tv_mode,10h ; DESQview active?
- jz chgdspndv ; z = no
- jmp chgdsx1 ; exit without screen change
- chgdspndv:
- mov ax,1683h ; Windows 3, get current virt machine
- int 2fh
- cmp ax,1683h ; virtual machine, if any
- je chgdspnw ; e = no Windows, do the video mode
- jmp chgdsx1 ; exit without screen change
- chgdspnw:mov ax,temp
- cmp crt_cols,80 ; are we narrow?
- jbe chgds3 ; be = narrow width now
- or al,al ; resetting to narrow width?
- jz chgds4 ; z = yes, do it
- jmp chgdsx1 ; else we are there now
- chgds3: or al,al ; resetting to narrow width?
- jnz chgds4 ; nz = no, setting to wide
- jmp chgdsx1 ; narrow width, we are there now
- chgds4: or ah,ah ; are we connected now?
- jnz chgds0 ; nz = no, skip flow control etc
- mov ah,flowoff ; get xoff
- or ah,ah ; flow control?
- jz chgds4a ; z = none
- call foutchr ; send it
- chgds4a:cmp byte ptr temp+1,0 ; exiting Connect mode?
- jne chgds0 ; ne = yes
- mov ax,200 ; wait 200 millisec before video tests
- call fpcwait ; so don't mix screen and port intrpts
-
- chgds0: call ckteva ; try Tseng Labs EVA
- jnc chgds1 ; nc = found
- call ckstbv ; try STB VEGA/EM
- jnc chgds1 ; nc = found
- call ckv7vd ; try Video 7 EGA Deluxe and VGA
- jnc chgds1 ; nc = found
- call ckatiw ; try ATI EGA Wonder
- jnc chgds1 ; nc = found
- call ckevrx ; try Everex Micro Enhancer Deluxe
- jnc chgds1 ; nc = found
- call ckevga ; try Everex EVGA-673
- jnc chgds1 ; nc = found
- call ckatt ; ATT boards
- jnc chgds1 ; nc = found
- call chkpa ; Paradise EGA/VGA boards
- jnc chgds1 ; nc = found
- call chkvesa ; VESA compatibles
- jnc chgds1 ; nc = found
- call ckxga ; IBM XGA
- jnc chgds1 ; nc = found
- mov si,offset cols80 ; name of 80 column file
- cmp byte ptr temp,0 ; setting 80 cols?
- je chgdsx2 ; e = yes
- mov si,offset cols132 ; use 132 column file
- chgdsx2:mov di,offset decbuf ; a temp buffer for path= usage
- call fstrcpy
- mov ax,di ; spath wants ptr in ax
- call fspath
- jc chgdsx ; c = file not found
- mov si,ax ; crun wants ptr in si
- call fcrun ; run the batch file, si = filespec
- call fserini ; reengage serial port, mode changes
- mov ax,0c06h ; clear kbd buffer and do function
- mov dl,0ffh ; console input
- int dos ; discard character(s)
- ; Perform mode change
- chgds1: cmp byte ptr temp+1,0 ; do without serial port xon/xoff?
- jne chgdsx1 ; ne = yes
- cmp flags.modflg,1 ; is mode line enabled?
- jbe chgdsx ; be = yes, and off or locally owned
- mov flags.modflg,1 ; remove foreign ownership
- chgdsx: mov ah,flowon ; get flow-on byte
- or ah,ah ; using flow control?
- jz chgdsx1 ; z = no
- call foutchr ; send it
- chgdsx1:call scrmod ; pick up current screen size
- pop di ; restore what we saved
- pop si
- pop dx
- pop cx
- pop bx
- pop ax
- pop es
- ret ; return to caller
-
- ; Individual tests for various 132-column boards
- ; Tseng LABS EVA, UltraPAK, ET4000
- ckteva: mov ax,0c000h ; seg addr for EVA
- mov es,ax ; set into es register
- mov di,76h ; offset of board's string
- lea si,tsngid ; validation string
- mov cx,tsnglen ; length of validiation string
- cld
- repe cmpsb ; compare strings
- je ckteva2 ; e = strings match
- mov ax,4d00h ; check for UltraPAK mono driver
- int screen
- cmp ax,5aa5h ; driver signature?
- jne ckteva4 ; ne = no
- mov ax,7 ; default to mono (7) for this board
- cmp byte ptr temp,0 ; setting 132 columns?
- je ckteva1 ; e = resetting to normal
- mov ax,18h ; set to 132 cols (Set Mode 18H)
- ckteva1:int screen
- clc ; carry clear means success
- ret
- ; an EVA board - check for 132 col kit
- ckteva2:cmp byte ptr es:099h,0 ; check 132 col kit installed
- jne catfnd ; ne = installed, do the mode change
- ckteva3:stc ; indicate adapter not present
- ret ; and exit
-
- ckteva4:mov dx,03cdh ; ET4000 test
- in al,dx ; Segment Select Register, get value
- push ax
- xor al,15h ; create test condition
- jmp $+2
- jmp $+2
- out dx,al ; set condition
- jmp $+2
- jmp $+2
- mov ah,al ; save condition
- in al,dx ; get new condition
- jmp $+2
- jmp $+2
- cmp ah,al ; did it work (same)?
- pop ax
- out dx,al ; restore original condition
- jne ckteva3 ; ne = no, ET4000 not present
- mov ax,3 ; default to cga 3
- cmp byte ptr temp,0 ; setting 132 columns?
- je ckteva5 ; e = resetting to normal
- mov ax,23h ; set to 132 cols (Set Mode 23H)
- ckteva5:int screen
- clc
- ret
- ;
- ckstbv: mov ax,0c000h ; STB's VGA/EM, VGA/EM-16, EM-16 Plus
- mov es,ax ;
- mov di,70h ; where to look for signature
- lea si,stbvid ; the signature
- mov cx,stbvlen ;
- cld ;
- repe cmpsb ; test
- je catfnd ; e = found
- mov di,70h ; where to look for signature
- lea si,stavid ; the signature
- mov cx,stavlen
- cld
- repe cmpsb ; test
- je catfnd ; e = found
- stc ; else say not there
- ret ;
- ; ATI EGA Wonder
- ckatiw: mov ax,0c000h ; seg addr for EGA Wonder
- mov es,ax ; set into es register
- mov di,012fh ; offset of message in ROM
- lea si,atiwid ; offset of message here
- mov cx,atilen ; length of validation string
- cld
- repe cmpsb ; compare strings
- je catfnd ; e = they match
- lea si,atiwid2 ; alternative signature
- mov di,30h ; start at this offset
- mov cx,atilen2 ; alternative signature length
- mov ax,es:[di] ; get first two bytes
- cmp al,atiwid2 ; string starts here?
- je ckatiw1 ; e = yes
- inc di ; try next location, just in case
- cmp ah,atiwid2 ; or here?
- je ckatiw1 ; e = yes
- stc ; strings differ
- ret
- ckatiw1:repe cmpsb ; check the whole string
- je catfnd ; e = matches the whole thing
- stc ; fail on mismatch
- ret
- catfnd: mov ax,0003h ; prepare to reset video mode
- cmp byte ptr temp,0 ; are we setting or resetting?
- je catfnd1 ; e is reset, exit
- mov ax,0023h ; set to 132 cols (Set Mode 23H)
- catfnd1:int screen
- clc ; carry clear means success
- ret
-
- chkpa: mov ax,0c000h ; load Paradise ROM BIOS address
- mov es,ax
- mov ax,0057h ; assume 132x25 mono display needed
- mov di,0009h ; load EGA board identifier index
- lea si,pmega1 ; Paradise Autoswitch Mono ident
- mov cx,pmegal1
- cld
- repe cmpsb ; do identification strings match?
- je chgpa2 ; e = yes, check num of display lines
- mov di,007dh ; no, load VGA board identifier index
- lea si,p30id ; Paradise VGA, other flavors
- mov cx,p30ln
- repe cmpsb ; do identification strings match?
- je chgpa1 ; e = yes, check for color mode
- stc ; fail
- ret
- chgpa1: cmp crt_norm,3 ; is the "normal" screen in color?
- ja chgpa2 ; a = no, orig assumption is correct
- mov ax,0055h ; assume 132x25 color required
- chgpa2: cmp crt_lins,25 ; is the "normal" screen 25 lines?
- jna chgpa3 ; na = yes, check num of cols needed
- dec ax ; change assumption to 132x43
- chgpa3: cmp byte ptr temp,0 ; switching to a 132 column mode?
- jne chgpa4 ; ne = yes
- mov al,crt_norm ; load "normal" display mode
- chgpa4: int screen ; issue BIOS call to change display
- clc ; success
- ret
- ; Video 7 Vega Deluxe
- ckv7vd: mov ax,0c000h ; seg addr for Vega rom bios
- mov es,ax ; set into es register
- mov di,002ah ; offset of message in ROM
- lea si,vid7id ; offset of message here
- mov cx,vid7len
- cld
- repe cmpsb ; compare strings
- je cnv7fn1 ; e = same
- mov di,002ah ; offset of ident string
- mov si,offset vid7id2 ; Video 7 VGA board
- mov cx,vid7len2
- repe cmpsb
- je cnv7fn2 ; e = found
- cnv7fx: stc ; strings are different
- ret
- ;
- cnv7fn1:test byte ptr es:[03ffeh],1 ; is this a 'Deluxe' Vega?
- jz cnv7fx ; z = nope, can't do it
- mov ah,35h ; DOS Get Vector
- mov al,10h ; Bios video interrupt
- int dos ; get it into es:bx
- mov di,bx ; es:bx is returned int 10h entry pnt
- sub di,5ah ; back offset to msg in 132X25.COM
- lea si,vid7id ; offset of validation message
- mov cx,vid7len ; length of validation string
- cld
- repe cmpsb ; Look for repeat of msg by 132X25.COM
- jne cnv7fn2 ; if different
- mov al,crt_mode ; prepare to reset video mode
- xor ah,ah
- cmp byte ptr temp,0 ; are we setting or resetting?
- je cnv7fn2a ; e is reset
- mov ax,0000h ; set to 132 cols (old 40x25)
- cnv7fn1a:int screen
- clc
- ret
-
- cnv7fn2:mov ax,6f00h ; check for VegaBios driver
- int screen
- cmp bx,'V7' ; Video 7 Bios presence response
- jne cnv7fx ; ne = not there
- mov ax,6f01h ; al gets monitor type (mono,color,ega)
- int screen
- mov bx,51h ; presume mono 132x25, page 0
- cmp crt_lins,42 ; 43 lines active?
- jb cnv7fn2a ; b = no
- inc bx ; use bx = 52h for 132x43
- cnv7fn2a:
- cmp al,10h ; analogue fixed freq (IBM 85xx)?
- je cnv7fx ; e = yes, no 132 columns
- cmp al,2 ; 1 = mono, 2 = color, above = ega
- jb cnv7fn3 ; b = mono or unknown
- mov bx,4fh ; presume med res color 132x25
- je cnv7fn3 ; e = med res color, al = 2
- mov bx,41h ; ega high res 132x25, enhanced mons
- cmp crt_lins,42 ; 43 lines active?
- jb cnv7fn3 ; b = no
- inc bx ; use bx = 42h for 132x43
- cnv7fn3:mov ax,6f05h ; set special mode found in bl
- cmp byte ptr temp,0 ; resetting to 80 column mode?
- jne cnv7fn4 ; ne = no, setting 132x25
- mov al,crt_norm ; get normal mode
- xor ah,ah ; set mode
- cmp crt_lins,42 ; 43 lines active?
- jb cnv7fn4 ; b = no
- mov bl,40h ; use Video 7 mode 40h 80x43 for color
- mov ax,6f05h ; and do special mode set
- cnv7fn4:int screen ; special mode is in bl
- mov ax,0f00h ; a nop screen bios command
- int screen
- clc
- ret
-
- ckevrx: mov ax,0c000h ; seg addr for Everex EV-659
- mov es,ax ; set into es register
- mov di,0047h ; offset of message in ROM
- lea si,evrxid ; offset of message here
- mov cx,evrxlen ; length of validation string
- cld
- repe cmpsb ; compare strings
- jne ckfnr2 ; ne = strings differ
- mov ah,crt_lins ; we recognize either 44 or 25 rows
- cmp ah,43 ; equal to 44-1 rows?
- jne ckfnr1 ; ne = no
- mov ax,0070h ; Everex extended mode ident
- mov bl,09h ; prepare to reset video mode to 80x44
- cmp byte ptr temp,0 ; are we setting or resetting?
- je ckfnr4 ; e is reset, exit
- mov bl,0bh ; 132x44
- int screen
- clc
- ret
- ckfnr1: cmp ah,24 ; equal to 25-1 rows?
- je ckfnr3 ; e = yes
- ckfnr2: stc ; return failure
- ret
- ckfnr3: mov ax,0003h ; prepare to reset video mode
- cmp byte ptr temp,0 ; are we setting or resetting?
- je ckfnr4 ; e is reset, exit
- mov ax,0070h ; Everex extended mode ident
- mov bl,0ah ; 132x25
- ckfnr4: int screen
- clc
- ret
- ckevga: mov ax,0c000h ; Everex FVGA-673, EV-678 rom segment
- mov es,ax
- mov di,76h ; offset in rom for board's id string
- lea si,evgid ; id string
- mov cx,evglen ; length of id string
- cld
- repe cmpsb ; do they match?
- je ckevg0 ; e = yes
- mov di,9dh ; offset in ROM for board's ID string
- lea si,evvid ; ID string
- mov cx,evvlen ; length of ID string
- cld
- repe cmpsb ; do they match?
- jne ckevg2 ; ne = no
- ckevg0: mov ax,3 ; prepare to reset video mode
- cmp byte ptr temp,0 ; setting or resetting mode?
- je ckevg1 ; e = resetting, exit
- mov ax,0070h ; mode for 132x25
- mov bl,0ah ; Everex mode 0ah
- ckevg1: int screen
- clc
- ret
- ckevg2: stc ; say board not found
- ret
- ; AT&T EGA/VGA boards
- ckatt: mov ax,0c000h ; seg of first signature
- mov es,ax
- mov si,offset attvdc6 ; first pattern
- mov di,35h ; test area
- cld
- mov cx,attvdlen ; length
- repe cmpsb
- je ckatt2 ; e = found
- mov cx,attvdlen ; try second signature, same length
- mov si,offset attvdc7
- mov ax,0e000h ; seg of second signature
- mov es,ax
- mov di,10h ; test area
- repe cmpsb
- je ckatt2 ; e = found
- stc ; not found
- ret
- ckatt2: mov al,crt_norm ; old mode
- xor ah,ah
- cmp byte ptr temp,0 ; resetting to 80 col?
- je ckatt3 ; e = yes
- mov ax,0055h ; 132 cols, set mode 55h
- ckatt3: int screen
- clc
- ret
- ; VESA compatibles
- chkvesa:mov di,seg rdbuf ; es:di is buffer for results
- mov es,di
- mov di,offset rdbuf
- mov ax,4f00h ; get SVGA information
- int screen
- cmp ax,4fh ; success?
- jne chkvesax ; ne = no
- cmp word ptr rdbuf,'EV' ; 'VESA'
- jne chkvesax ; ne = no
- cmp word ptr rdbuf+2,'AS'
- jne chkvesax ; ne = no
- mov ax,4f01h ; get mode info to es:di buffer
- mov cx,109h ; 109h is 132x25 text
- int screen
- cmp ax,4fh ; success?
- jne chkvesax ; ne = no
- mov bx,3 ; assume 80 columns
- cmp byte ptr temp,0 ; setting or resetting mode?
- je chkvesa2 ; e = resetting
- mov bx,109h ; mode for 132x25
- chkvesa2:mov ax,4f02h ; set mode from bx
- int screen
- cmp ax,4fh ; success?
- jne chkvesax ; ne = no
- clc ; say success
- ret
- chkvesax:stc ; say failure
- ret
-
- ; IBM XGA 132 columns
- ckxga: push bp ; (old BIOSes are still around)
- push ds ; set es to data segment
- pop es
- mov ax,1b00h ; get functionality table
- xor bx,bx
- mov di,offset decbuf ; es:di is 64 bytes of workspace
- int screen
- cmp al,1bh ; is this call supported?
- jne ckxgax ; ne = no, fail
- les bx,dword ptr decbuf ; get the address of the modes info
- test byte ptr es:[bx+2],10h ; is mode 14h supported?
- jz ckxman ; z = no, try manual method for now
- mov ax,3 ; assume resetting to mode 3, 80x25
- cmp byte ptr temp,0 ; setting 132 columns?
- je ckxga1 ; e = no, resetting to 80 columns
- mov ax,14h ; invoke IBM XGA mode 14h, 132x25
- ckxga1: int screen
- ckxga2: pop bp
- clc ; say success
- ret
- ckxgax: pop bp
- mov xga_reg_base,-2 ; flag saying no XGA Adapter found
- stc ; say failure
- ret
-
- ckxman: call xgaman ; do tests/sets manually
- pop bp
- jnc ckxman1 ; nc = success
- mov xga_reg_base,-2 ; flag saying no XGA Adapter found
- ckxman1:ret
- chgdsp endp
-
- ; XGA mode setting via going to the hardware manually
- ; Code furnished by Bert Tyler, National Institue of Health
-
- xgaman proc near
- cmp xga_reg_base,-2 ; has the XGA detector already failed?
- je xgafail ; e = yes, fail again
- cmp xga_reg_base,-1 ; have we already found the XGA?
- je xga_loc ; e = no
- jmp xga_do1 ; yes, process it
- xga_loc:push es
- mov ah,35h ; DOS get interrupt vector
- mov al,15h ; Int 15h
- int dos ; returns vector in es:bx
- mov ax,es ; segment part
- pop es
- or ax,ax ; undefined vector?
- jz xgafail ; z = yes
- mov dx,-1 ; start with an invalid POS address
- mov ax,0c400h ; look for POS base address
- int 15h ; (Microchannel machines only)
- jc xgafail ; c = error, not a MC machine
- mov word ptr decbuf,dx ; save pos_base_address
- xor cx,cx ; check all MCA slots & motherboard
- cmp dx,-1 ; do we have a good POS?
- jne xga_lp1 ; ne = yes, proceed with MCA checks
- xgafail:stc ; fail
- ret
-
- xga_lp1:cli ; no interrupts, please
- cmp cx,0 ; treat the motherboard differently?
- jne xga_sk4 ; ne = yes
- mov al,0dfh ; enable the motherboard for setup
- mov dx,94h
- out dx,al
- jmp short xga_sk5
- xga_sk4:mov ax,0c401h ; enable an MCA slot for setup
- mov bx,cx ; this slot
- int 15h
- xga_sk5:mov dx,word ptr decbuf ; get pos record for the slot
- in ax,dx ; ID
- mov word ptr decbuf+2,ax
- add dx,2 ; compute IO Res Base
- in al,dx ; get POS data byte1
- and ax,0eh ; muck about with it to get reg base
- shl ax,1
- shl ax,1
- shl ax,1
- add ax,2100h
- mov xga_reg_base,ax
- cmp cx,0 ; treat the motherboard differently?
- jne xga_sk6 ; ne = yes
- mov al,0ffh ; enable the motherboard for normal
- out 094h,al
- jmp short xga_sk7
- xga_sk6:mov ax,0c402h ; enable the MCA slot for normal
- mov bx,cx ; this slot
- int 15h
- xga_sk7:sti ; interrupts on again
-
- mov ax,word ptr decbuf+2 ; is an XGA adapter on this slot?
- cmp ax,08fd8h
- jae xga_sk8 ; ae = yes
- jmp xga_lp2 ; try another slot
- xga_sk8:cmp ax,08fdbh ; still within range?
- jbe xga_sk9 ; be = yes
- jmp xga_lp2 ; no, try another slot
- xga_sk9:mov dx,xga_reg_base ; is there a monitor on this slot?
- add dx,0ah
- mov al,052h
- out dx,al
- mov dx,xga_reg_base
- add dx,0bh
- in al,dx
- and al,0fh
- cmp al,0fh
- jne xga_ska ; ne = yes
- jmp xga_lp2 ; no
- xga_ska:mov dx,xga_reg_base ; is this XGA in VGA mode?
- in al,dx
- test al,1
- jnz xga_do1 ; nz = yes, found it!
-
- xga_lp2:inc cx ; try another adapter?
- cmp cx,9 ; done all slots?
- ja xga_no ; a = yes
- jmp xga_lp1 ; no, try another slot
- xga_no: jmp xgafail ; fail
-
- ; *finally* put the XGA into 132-column or 80-column mode
-
- xga_do1:cmp byte ptr temp,0 ; setting 80-column mode?
- jne xga_do2 ; ne = no, 132 columns
- jmp xga_do3 ; do 80 column mode
-
- ; 132-column mode routine
- xga_do2:mov dx,xga_reg_base ; (the manual doesn't explain...)
- add dx,0ah
- mov ax,1550h
- out dx,ax
- mov ax,1450h
- out dx,ax
- mov ax,0454h
- out dx,ax
- mov ax,1202h ; select 400 scan lines
- mov bl,30h
- int screen
- mov ax,0+3 ; set video mode 3
- int screen
-
- mov dx,xga_reg_base ; (the manual doesn't explain...)
- add dx,0ah
- mov al,50h
- out dx,al
- inc dx
- in al,dx
- or al,1
- out dx,al
-
- mov dx,xga_reg_base ; (the manual doesn't explain...)
- add dx,0ah
- mov al,50h
- out dx,al
- inc dx
- in al,dx
- and al,0fdh
- out dx,al
-
- mov dx,xga_reg_base ; (the manual doesn't explain...)
- add dx,0ah
- mov al,50h
- out dx,al
- inc dx
- in al,dx
- and al,0fch
- out dx,al
-
- mov dx,xga_reg_base ; (the manual doesn't explain...)
- mov al,3
- out dx,al
-
- mov dx,xga_reg_base ; (the manual doesn't explain...)
- add dx,0ah
- mov ax,0154h
- out dx,ax
- mov ax,8070h
- out dx,ax
-
- mov dx,xga_reg_base ; (the manual doesn't explain...)
- add dx,0ah
- mov al,50h
- out dx,al
- inc dx
- in al,dx
- and al,0efh
- out dx,al
-
- mov dx,03d4h ; (the manual doesn't explain...)
- mov ax,11h
- out dx,al
- inc dx
- in al,dx
- and al,7fh
- out dx,al
-
- mov dx,03d4h ; (the manual doesn't explain...)
- mov ax,0
- out dx,al
- inc dx
- mov ax,0a4h
- out dx,al
-
- mov dx,03d4h ; (the manual doesn't explain...)
- mov ax,1
- out dx,al
- inc dx
- mov ax,83h
- out dx,al
-
- mov dx,03d4h ; (the manual doesn't explain...)
- mov ax,2
- out dx,al
- inc dx
- mov ax,84h
- out dx,al
-
- mov dx,03d4h ; (the manual doesn't explain...)
- mov ax,3
- out dx,al
- inc dx
- mov ax,83h
- out dx,al
-
- mov dx,03d4h ; (the manual doesn't explain...)
- mov ax,4
- out dx,al
- inc dx
- mov ax,90h
- out dx,al
-
- mov dx,03d4h ; (the manual doesn't explain...)
- mov ax,5
- out dx,al
- inc dx
- mov ax,80h
- out dx,al
-
- mov dx,xga_reg_base ; (the manual doesn't explain...)
- add dx,0ah
- mov ax,0a31ah
- out dx,ax
- mov ax,001bh
- out dx,ax
-
- mov dx,03d4h ; (the manual doesn't explain...)
- mov ax,13h
- out dx,al
- inc dx
- mov ax,42h
- out dx,al
-
- mov dx,03d4h ; (the manual doesn't explain...)
- mov al,11h
- out dx,al
- inc dx
- in al,dx
- or al,80h
- out dx,al
-
- mov dx,xga_reg_base ; (the manual doesn't explain...)
- add dx,0ah
- mov al,50h
- out dx,al
- inc dx
- in al,dx
- or al,3
- out dx,al
-
- mov dx,03c4h ; (the manual doesn't explain...)
- mov ax,1
- out dx,al
- inc dx
- in al,dx
- or al,1
- out dx,al
-
- mov dx,03dah ; (the manual doesn't explain...)
- in al,dx
-
- mov dx,003c0h ; (the manual doesn't explain...)
- mov al,13h
- out dx,al
- xor al,al
- out dx,al
- mov al,20h
- out dx,al
-
- mov ax,40h ; tell the BIOS we have 132 columns
- mov es,ax
- mov byte ptr es:[4ah],132 ; set Bios screen width data area
- clc ; return success
- ret
- ; Set 80 column mode
- xga_do3:mov dx,xga_reg_base ; (the manual doesn't explain...)
- add dx,01h
- xor al,al
- out dx,al
-
- mov dx,xga_reg_base ; (the manual doesn't explain...)
- add dx,4
- xor al,al
- out dx,al
-
- mov dx,xga_reg_base ; (the manual doesn't explain...)
- add dx,5
- mov al,0ffh
- out dx,al
-
- mov dx,xga_reg_base ; (the manual doesn't explain...)
- add dx,0ah
- mov ax,0ff64h
- out dx,ax
-
- mov dx,xga_reg_base ; (the manual doesn't explain...)
- add dx,0ah
- mov ax,1550h
- out dx,ax
-
- mov dx,xga_reg_base ; (the manual doesn't explain...)
- add dx,0ah
- mov ax,1450h
- out dx,ax
-
- mov dx,xga_reg_base ; (the manual doesn't explain...)
- add dx,0ah
- mov ax,0051h
- out dx,ax
-
- mov dx,xga_reg_base ; (the manual doesn't explain...)
- add dx,0ah
- mov ax,0454h
- out dx,ax
-
- mov dx,xga_reg_base ; (the manual doesn't explain...)
- add dx,0ah
- mov ax,7f70h
- out dx,ax
-
- mov dx,xga_reg_base ; (the manual doesn't explain...)
- add dx,0ah
- mov ax,202ah
- out dx,ax
-
- mov dx,xga_reg_base ; (the manual doesn't explain...)
- ;; add dx,00h
- mov al,1
- out dx,al
-
- mov dx,03c3h ; (the manual doesn't explain...)
- mov al,1
- out dx,al
-
- mov ax,1202h ; select 400 scan lines
- mov bl,30h
- int screen
- mov ax,0+3 ; set video mode 3
- int screen
- clc ; return success
- ret
- xgaman endp
-
- ; Routine to do keyclick if flag is set, no arguments
- vclick proc near
- test vtemu.vtflgop,vskeyclick ; is keyclick flag on?
- jz vclick1 ; z = no, just return
- push bx
- push di
- mov di,500 ; 500 Hertz
- mov bx,1 ; For 1 millisecond
- call vtsound ; Do it
- pop di ; Restore the ACs
- pop bx
- vclick1:ret
- vclick endp
-
- ; Routine to do VT100-style bell, no arguments
- fvtbell proc far
- call vtbell
- ret
- fvtbell endp
-
- vtbell proc near
- cmp belltype,1 ; visual bell?
- je vtbell1 ; e = yes
- ja vtbell2 ; a = no bell
- push di ; audible bell
- push bx
- mov di,880 ; 880 Hertz
- mov bx,40 ; For 40 ms
- call vtsound ; Do it
- pop bx
- pop di
- ret
- vtbell1:call revscn ; reverse screen
- push ax
- mov ax,40 ; for 40 milliseconds
- call fpcwait
- pop ax
- call revscn ; put back
- vtbell2:ret
- vtbell endp
-
- ; Routine to make noise of arbitrary frequency for arbitrary duration.
- ; Similar to routine (with typo removed) in "IBM PC Assembly Language:
- ; A Guide for Programmers", Leo J. Scanlon, 1983 Robert J. Brady Co.,
- ; Bowie, MD., page 270. Modified by J R Doupnik to use 0.1 millsec interval.
- ; Call: di/ frequency in Hertz.
- ; bx/ duration in 1 millisecond units
- vtsound proc near
- push ax ; save regs
- push cx
- push dx
- mov al,0B6H ; write timer mode register
- out 43H,al
- mov dx,14H ; timer divisor is
- mov ax,4F38H ; 1331000/frequency
- div di
- out 42H,al ; write timer 2 count low byte
- mov al,ah
- out 42H,al ; write timer 2 count high byte
- in al,61H ; get current port B setting
- or al,3 ; turn speaker on
- out 61H,al
- mov ax,bx ; number of milliseconds to wait
- call fpcwait ; do the calibrated wait
- in al,61H ; get current port B setting
- and al,0fch ; turn off speaker and timer
- out 61H,al
- pop dx ; restore regs
- pop cx
- pop ax
- ret
- vtsound endp
- code1 ends
- end
-